【问题标题】:XmlPath (eclipselink, MOXy) is not working or is it?XmlPath (eclipselink, MOXy) 不工作,是吗?
【发布时间】:2022-01-19 23:06:34
【问题描述】:

我发现 XmlPath 的一个“奇怪”行为有时会提供与 XPath 相关联的 an object,有时只提供 null

我花了几个小时才发现它是如何发生的,这样您就不必浪费时间了。
但我仍然对这种行为的“为什么”感到好奇。

要重新创建案例,您将需要 eclipselink 和(使用较新的 Java)jaxb-api:

        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.7.10</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>

XML 文件非常简单(lorem.xml):

<?xml version="1.0" encoding="UTF-8" ?>
<lorem>
    <name>Smith</name>
    <foo>
        <bar x="5">
            <ipsum>8888</ipsum>
        </bar>
    </foo>
</lorem>

Lorem.java

package forum;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name = "lorem")
@XmlAccessorType(XmlAccessType.FIELD)
public class Lorem
{
    @XmlElement
    Foo foo;

    @XmlPath("foo/bar")
    Bar obj3;

    @XmlPath("name/text()")
    String name;
}

Foo.java

package forum;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class Foo
{
    @XmlElement
    private Bar bar;
}

Bar.java

package forum;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class Bar
{
    @XmlAttribute(name = "x")
    public String valX;

    @XmlElement
    private String ipsum;
}

DemoLorem.java

package forum;

import java.io.File;
import java.util.Properties;

import javax.xml.bind.JAXB;

public class DemoLorem
{

    public static void main(String[] args) throws Exception
    {
        
        Properties props = System.getProperties();
        props.setProperty("javax.xml.bind.context.factory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
        props.setProperty("javax.xml.bind.JAXBContextFactory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
        
        Lorem lorem = JAXB.unmarshal(new File("lorem.xml"), Lorem.class);       
        System.out.println(lorem.obj3.valX);
        JAXB.marshal(lorem, System.out);
    }
}

在这种情况下,我们会收到以下错误:

Exception in thread "main" java.lang.NullPointerException: Cannot read field "valX" because "lorem.obj3" is null
    at forum.DemoLorem.main(DemoLorem.java:19)

"lorem.obj3" 为 null 是 foo 的子对象。

但是当我们像这样修改 Lorem.java 时:

//  @XmlElement
//  private Foo foo;

突然一切正常,我们得到:

5                                      <--- this is value of lorem.obj3.valX
<?xml version="1.0" encoding="UTF-8"?>
<lorem>
   <foo>
      <bar x="5">
         <ipsum>8888</ipsum>
      </bar>
   </foo>
   <name>Smith</name>
</lorem>

为了确保 XPath 在这两种情况下都能正常工作,有 name 字段作为参考。

当我们没有引用父对象的 XmlElement (foo) 时,XPath 被正确解析并得到 (bar)。
在相反的情况下,bar 为空。为什么 XPath 没有解析?

我明白了,我可以从foo 得到bar。为什么添加一个引用会影响(中断)另一个?

为什么?

【问题讨论】:

    标签: java xml moxy


    【解决方案1】:

    问题本身解释了问题的根源和how 来处理它,这对其他开发人员可能有用。

    如果能在why 上获得一些 cmets 会很高兴,因为一开始就有这样的行为。 这很令人困惑,但也许这背后是有原因的。技术或任何其他。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-14
      • 2012-02-02
      • 2012-08-09
      • 2012-12-01
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      相关资源
      最近更新 更多