使用 MOXy 和 XPath,是否可以解组属性列表?

发布于 2024-11-27 16:31:31 字数 1550 浏览 1 评论 0原文

编辑:这是我加载 XML 文档的方式,正如我在 Blaise 的回答中使用的那样。我这样加载它是因为我想使用一个节点,而不是整个文档。即使使用整个文档,以这种方式加载时我仍然遇到问题。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("[path to doc]/input.xml");
TestClass testClass = (TestClass) unmarshaller.unmarshal(doc);

我有一个如下所示的 XML:

<test>
  <items>
    <item type="cookie">cookie</item>
    <item type="crackers">crackers</item>
  </items>
</test>

和一个类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestClass
{
  @XmlPath("items/item/text()")
  @XmlElement
  private ArrayList<String> itemList = new ArrayList<String>();

  // getters, setters omitted
}

无论我是否有 @XmlElement,上面的代码都将起作用,并且我得到一个包含 [cookie、crackers] 的 ArrayList。

如果我将上面的声明更改为

@XmlPath("items/item/@type")
@XmlElement
private ArrayList<String> itemList = new ArrayList<String>();

我的 ArrayList 为空。

我的最终目标是只拥有属性,以便我的 XML 看起来像这样:

<test>
  <items>
    <item type="cookie"/>
    <item type="crackers"/>
  </items>
</test>

我正在尝试做的是,使用 XPath 提取属性列表,可能吗?如果可以,如何实现?

谢谢。

Edit: here's how I'm loading the XML document, as I used it in Blaise's answer. I'm loading it like this because I want to work with a node, not the whole doc. Even using the whole document I'm still having trouble when loading in this manner.

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("[path to doc]/input.xml");
TestClass testClass = (TestClass) unmarshaller.unmarshal(doc);

I've got XML that looks like this:

<test>
  <items>
    <item type="cookie">cookie</item>
    <item type="crackers">crackers</item>
  </items>
</test>

And a class:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestClass
{
  @XmlPath("items/item/text()")
  @XmlElement
  private ArrayList<String> itemList = new ArrayList<String>();

  // getters, setters omitted
}

The above code will work whether or not I have @XmlElement, and I get an ArrayList containing [cookie, crackers].

If I change the declaration above to

@XmlPath("items/item/@type")
@XmlElement
private ArrayList<String> itemList = new ArrayList<String>();

my ArrayList is empty.

My ultimate goal is to just have attributes so my XML would look like this:

<test>
  <items>
    <item type="cookie"/>
    <item type="crackers"/>
  </items>
</test>

Is what I'm trying to do, pull out a list of attributes using XPath, possible, and if so, how?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

宫墨修音 2024-12-04 16:31:31

更新

我已经能够确认您所看到的问题(https://bugs.eclipse .org/353763)。我们的 EclipseLink 2.3.1 和 2.4.0 流中已添加修复程序,可以从 2011 年 8 月 4 日开始的夜间下载页面获取:

解决方法:

您可以通过设置DocumentBuilderFactory 了解命名空间:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse("src/forum6907225/input.xml");
    testClass = (TestClass) unmarshaller.unmarshal(doc);
    marshaller.marshal(testClass, System.out);

您正在正确执行映射(见下文)。您是否包含了 jaxb.properties 文件来指定 EclipseLink MOXy 作为您的 JAXB 提供程序?:

  • < a href="http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html" rel="nofollow">http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html

测试类

package forum6907225;

import java.util.ArrayList;

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

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

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestClass
{
    @XmlPath("items/item/@type")
    @XmlElement
    private ArrayList<String> itemList = new ArrayList<String>();

  // getters, setters omitted
}

演示

package forum6907225;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.eclipse.persistence.Version;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(TestClass.class);
        System.out.println(Version.getVersionString());

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum6907225/input.xml");
        TestClass testClass = (TestClass) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(testClass, System.out);
    }

}

<强>输入.xml

<?xml version="1.0" encoding="UTF-8"?>
<test>
  <items>
    <item type="cookie">cookie</item>
    <item type="crackers">crackers</item>
  </items>
</test>

<强>输出

2.3.1.qualifier
<?xml version="1.0" encoding="UTF-8"?>
<test>
   <items>
      <item type="cookie"/>
      <item type="crackers"/>
   </items>
</test>

UPDATE

I have been able to confirm the issue you are seeing (https://bugs.eclipse.org/353763). A fix has been added into our EclipseLink 2.3.1 and 2.4.0 streams and can be obtained from the nightly download page starting August 4th, 2011:

Workaround:

You can workaround this issue by setting your DocumentBuilderFactory to be namespace aware:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse("src/forum6907225/input.xml");
    testClass = (TestClass) unmarshaller.unmarshal(doc);
    marshaller.marshal(testClass, System.out);

You are doing the mapping correctly (see below). Have you included a jaxb.properties file to specify EclipseLink MOXy as your JAXB provider?:

Test Class

package forum6907225;

import java.util.ArrayList;

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

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

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "test")
public class TestClass
{
    @XmlPath("items/item/@type")
    @XmlElement
    private ArrayList<String> itemList = new ArrayList<String>();

  // getters, setters omitted
}

Demo

package forum6907225;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.eclipse.persistence.Version;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(TestClass.class);
        System.out.println(Version.getVersionString());

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum6907225/input.xml");
        TestClass testClass = (TestClass) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(testClass, System.out);
    }

}

input.xml

<?xml version="1.0" encoding="UTF-8"?>
<test>
  <items>
    <item type="cookie">cookie</item>
    <item type="crackers">crackers</item>
  </items>
</test>

Output

2.3.1.qualifier
<?xml version="1.0" encoding="UTF-8"?>
<test>
   <items>
      <item type="cookie"/>
      <item type="crackers"/>
   </items>
</test>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文