【问题标题】:Update partial XML mapping to bean更新部分 XML 映射到 bean
【发布时间】:2012-04-16 19:21:15
【问题描述】:

我需要将节点的 xml 文件子集映射到 Java Bean。

例如地图

<data>
    <field1>Value</field1>
    <field2>Value</field2>
    <field3>Value</field3>
    <field4>Value</field4>
    <field5>Value</field5>
</data>

public class DataBean {
    private String field2;
    private String field5;
    // ...getter/setter
}

然后操作 bean 并更新源 xml 文件,而不会丢失未映射的元素。 我该如何使用它? 什么图书馆?

感谢您的帮助, 毛里齐奥

【问题讨论】:

标签: java xml javabeans xmlbeans xmlmapper


【解决方案1】:

如果您决定 xml 结构中的内容,那么您可以使用 XStream (http://x-stream.github.io/) 进行序列化和反序列化。 但是如果你只是从 xml 反序列化为 bean(从外国格式),那么你应该使用 Smooks (http://www.smooks.org/)。

与 JAXB 相比,这两个库都非常轻量级。 JAXB 不灵活,需要创建 XML Schema。我不推荐,因为与创建简单的 DOM 解析相比,您浪费的时间更多。

JAXB 非常学术。示例:许多“SOAP 信封”没有完全由 WSDL 文档描述,而是在 WSDL 字段中(在一个简单的文本字段中)添加了一些 xml。在这种情况下,您会浪费大量时间来创建 JAXB 基础架构...

当然这只是我个人的看法。但是请记住这两个工具并尝试使用它们。你会发现它真的很值得。

【讨论】:

  • 所以使用 XStream 我能够更新源 xml 文档,只更改映射字段并让其他 xml 元素保持不变?
  • JAXB (JSR-222) 实现不需要 XML 模式 (wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted/…),与 XStream (blog.bdoughan.com/2010/10/how-does-jaxb-compare-to-xstream.html) 相比,它非常轻量且易于使用。 JAXB 被 JAX-WS 用来创建 SOAP 消息,但也可以单独使用。 JAXB 几乎不是“学术”,因为它用于更多的企业应用程序。
  • Blaise:JAXB 需要描述数据类型的模式,请查看jaxb.java.net/tutorial/…jaxb.java.net/tutorial/…。 JAXB 当然包含模式构建器。
  • @wojand - 相信我,JAXB (JSR-222) 实现不需要 XML 模式。更多示例请查看我的博客:blog.bdoughan.com
  • Maurizio:XStream 旨在编写 XML sn-ps。因此,您不需要编写任何定义 xml 结构的 xml 文档。但这只是序列化工具。可能比 JAXB 快,因为可以使用 XPP 解析器。对于绑定外国格式,Smooks 更好。不要误解我的意思,JAXB 是不错的工具 :-) 一切都取决于你真正需要它。
【解决方案2】:

注意:我是EclipseLink JAXB (MOXy) 领导,是JAXB 2 (JSR-222) 专家组的成员。

以下是 MOXy 的 JAXB Binder 实现如何做到这一点:

DataBean

package forum9988170;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="data")
public class DataBean {

    private String field2;
    private String field5;

    public String getField2() {
        return field2;
    }

    public void setField2(String field2) {
        this.field2 = field2;
    }

    public String getField5() {
        return field5;
    }

    public void setField5(String field5) {
        this.field5 = field5;
    }

}

jaxb.properties

要将 MOXy 指定为您的 JAXB 提供程序,您需要在与域类相同的包中添加一个名为 jaxb.properties 的文件,并使用以下条目,

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

演示

package forum9988170;

import java.io.File;
import javax.xml.bind.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(DataBean.class);

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        File xml = new File("src/forum9988170/input.xml");
        Document document = db.parse(xml);

        Binder<Node> binder = jc.createBinder();
        DataBean dataBean = (DataBean) binder.unmarshal(document);
        dataBean.setField2("NEW FIELD 2");
        dataBean.setField5("NEW FIELD 5");
        binder.updateXML(dataBean);

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        DOMSource source = new DOMSource(document);
        StreamResult result = new StreamResult(System.out);
        t.transform(source, result);
    }

}

输出

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data>
    <field1>Value</field1>
    <field2>NEW FIELD 2</field2>
    <field3>Value</field3>
    <field4>Value</field4>
    <field5>NEW FIELD 5</field5>
</data>

更多信息

【讨论】:

  • 伟大的作品非常好,并且使用 EclipseLink 我可以使用 xpath 进行映射,非常漂亮。但是,如果我不需要 @XmlPath 我可以对标准 JAXB 做同样的事情吗?
  • @MaurizioMerli - EclipseLink MOXy 是通过所有 JAXB 和 Java EE 合规性测试的标准 JAXB/JSR-222 (jcp.org/en/jsr/detail?id=222) 实现。我成为该专家组的成员已有一段时间了(请参阅 JAXB 规范的第 1.5 节)。 Binder 的 JAXB 参考实现实现似乎有所不同,我一直认为这是该实现中的一个错误。
猜你喜欢
  • 2012-10-11
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 2017-08-12
  • 2018-09-14
  • 2012-04-30
  • 1970-01-01
  • 2012-01-23
相关资源
最近更新 更多