【问题标题】:Java object to XML Elements?Java 对象到 XML 元素?
【发布时间】:2011-02-15 11:46:15
【问题描述】:

我正在开发一个 web 服务客户端应用程序,而且我大部分时间都在工作。我可以很好地从第三方网络服务中检索和读取数据。现在我需要提交一些数据,但我卡住了。

我正在检索/提交的对象的类是通过 xjc 工具从 XSD 文件生成的。我坚持的部分是将这些对象之一转换为 XML 树以提交给 Web 服务。

当我从/向 ws 检索/发送请求时,它包含一个“有效负载”对象。这在 java 代码中定义为(部分列表):

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PayloadType", propOrder = {
    "compressed",
    "document",
    "any",
    "format"
})
public class PayloadType {

    @XmlElement(name = "Compressed")
    protected String compressed;
    @XmlElement(name = "Document")
    protected List<String> document;
    @XmlAnyElement
    protected List<Element> any;
    protected String format;

    public List<Element> getAny() {
        if (any == null) {
            any = new ArrayList<Element>();
        }
        return this.any;
    }

}

我关心的唯一字段是包含 XML 树的“任何”字段。当我从 ws 检索数据时,我使用如下内容读取该字段: ('root' 是 org.w3c.dom.Element 类型,是在负载对象上调用 'getAny().get(0)' 的结果)

NodeList nl = root.getElementsByTagName("ns1:Process"); // "ns1:Process" is an XML node to do something with
if (nl != null && nl.getLength() > 0) {
    for (int i = 0; i < nl.getLength(); i++) {
        Element proc = (Element) nl.item(i);
        try {
            // do something with the 'proc' Element here...
        } catch (Exception ex) {
            // handle problems here...
        }
    }
}

提交数据是我卡住的地方。如何获取从 XSD 生成的类之一创建的 java 对象并将其转换为可以添加到有效负载对象的“任何”列表中的 Element 对象?例如,如果我有一个 DailyData 类并且我创建并使用数据填充它:

DailyData dData = new DailyData();
dData.setID = 34;
dData.setValues = "3,5,76,23";

如何将该“dData”对象添加到有效负载对象的“任何”列表中?它必须是一个元素。我是否使用 JAXBContext 编组器做某事?我用它来将“dData”对象转储到屏幕上以检查 XML 结构。

我确定答案正盯着我看,但我就是看不到它!

戴夫

更新:可以使用以下代码 sn-p:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = dbf.newDocumentBuilder().newDocument();

JAXBContext context = JAXBContext.newInstance(DailyData.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(dData, doc);


PayloadType payload = new PayloadType();
payload.getAny().add((Element)doc.getFirstChild());

【问题讨论】:

  • 认为我已经弄明白了,但是直到我们在 DEV 环境中获得一些测试数据后我才能确定。如果结果是正确的,我会发布我的答案。
  • 你应该已经回答了你自己的问题,因为我会投赞成票 :-) 这是最有用的。

标签: java xml web-services jaxb


【解决方案1】:

List&lt;Element&gt; 字段类型通常由 XJC 在架构中有类似内容时生成:

<xs:any processContents="skip" maxOccurs="unbounded" minOccurs="0" />

这里的关键是processContents="skip",意思是“任何事情都可以”——任何格式良好的XML 都可以进入这里。因为它是免费的,所以 XJC 所能做的就是将其表示为 DOM,而处理该有效负载成为您的责任。

如果您删除 processContents="skip",那么 JAXB 将尝试将有效负载绑定到对象模型,前提是它可以将有效负载 XML 匹配到 JAXBContext 中的类。在这种情况下,XJC 将生成List&lt;Object&gt; 类型的字段。

这看起来不像是一种改进,但这个List 可以包含Element(如果JAXBContext 不能将有效负载识别为它可以绑定的东西),或者JAXBElement(如果它可以识别它)。后者包含有效载荷的绑定版本,并且更容易处理。

这一切都在here进一步描述。

如果您无法修改架构,并且被processContents="skip" 卡住,那么您将不得不跳槽。您可以构建另一个知道您的有效负载类的JAXBContext,并使用它来编组到Element(使用marshaller.marshal(payload, new DOMResult()) 之类的东西。然后您可以将该元素转储到有效负载中。

【讨论】:

  • 感谢您的解释,我会查看链接。由于 XSD 文件是由第三方提供的,我不想更改它们。所以,跳圈就是了!我这样做的方式涉及与您的建议类似的编组。我的代码运行没有错误;一旦测试数据在他们的系统中可用,测试将是查看“他们的”网络服务是否接受我发送的内容......
  • 按建议工作!我已将代码放在原始问题的底部。
【解决方案2】:

首先,任何类型的元素都可以在其中包含任何 XML。因此,即使您在其中添加 DailyData 类 XML 表示形式,Schema 验证也应该可以正常工作。

现在关于编组 DailyData 类的其他问题。如果这个类是使用 xjc 编译器本身生成的,那么这个类(或其他生成的类)应该已经知道将这个对象转换为 XML 的方法。

我没有直接使用这个,但是下面的链接应该对你有帮助

http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/rwbs_xjc.html

【讨论】:

    猜你喜欢
    • 2013-03-01
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多