【问题标题】:Add XML comments into marshaled file将 XML 注释添加到编组文件中
【发布时间】:2010-11-23 18:27:11
【问题描述】:

我正在将对象编组到 XML 文件中。如何将 cmets 添加到该 XML 文件中?

【问题讨论】:

  • 以防万一管理 JAXB 的人正在监听 - 我其次需要添加 cmets(以及用于漂亮打印的换行符),即需要在编组期间将节点插入 DOM 树。

标签: java xml jaxb


【解决方案1】:

如果现在有人像我一样遇到这个问题,值得指出的是,现在执行此操作的属性是com.sun.xml.bind.xmlHeaders(似乎不再是内部的),所以您可以像这样解决问题(我有只用 EclipseLink MOXY 试过):

JAXBContext context = JAXBContext.newInstance(Player.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty("com.sun.xml.bind.xmlHeaders", "\n<!-- Test Comment -->");
m.marshal(player, System.out);

以下信息最初来自Marshaller PropertiesJAXB RI Extensionsjaxb.java.net 文档中的Marshaller Properties

XML 前导控制

此属性允许您指定 XML 前导码 ( 声明)和任何其他 PI、cmets、DOCTYPE 声明 紧随其后。此属性仅在您是 编组到 OutputStream、Writer 或 StreamResult。请注意,这 属性与 Marshaller.JAXB_FRAGMENT 属性交互。如果说 属性未更改或设置为 false,则 JAXB 将始终写入 它的 XML 前导码,所以这个属性只能用于编写 PI, cmets、DOCTYPE 等。另一方面,如果设置为 true,则 JAXB 不会编写自己的 XML 前导码,因此该属性可能包含 自定义 XML 序言。

【讨论】:

    【解决方案2】:

    您可以使用专有 Marshaller 属性 com.sun.xml.bind.xmlHeaders (see XML Preamble Control) 在序言之后添加 cmets

    在包含的 JAXB 实现 jdk1.6.0_29 中,该属性称为“com.sun.xml.internal.bind.xmlHeaders”

    另见问题:How to add DOCTYPE and xml processing instructions when marshalling with JAXB?

    因此,要在序言之后获取带有测试注释的 XML:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!-- Test Comment -->
    <player>
        <name>Daniel</name>
        <birthday>1982-06-09T00:00:00+02:00</birthday>
    </player>
    

    您可以使用以下 Java 代码:

    JAXBContext context = JAXBContext.newInstance(Player.class);
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    m.setProperty("com.sun.xml.internal.bind.xmlHeaders", "\n<!-- Test Comment -->");
    m.marshal(player, System.out);
    

    【讨论】:

    • 不适用于 jaxb-impl-2.2.6-b35,setProperty("com.sun.xml.internal.bind.xmlHeaders", ...) 因 PropertyException 而失败
    • @MartinVysny 考虑 com.sun.xml.internal.bind.xmlHeaders
    【解决方案3】:

    我没有看到单独使用 JAXB 的方法。但是,我认为您可以利用 DOM 来获得所需的效果:

    final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    final DocumentBuilder builder = factory.newDocumentBuilder();
    final Document doc = builder.getDOMImplementation().createDocument(null, null, null);
    
    final Binder<Node> binder = jaxbContext.createBinder();
    binder.marshal(jaxbObject, doc);
    final Comment comment = doc.createComment("This is a comment");
    doc.appendChild(comment);
    
    final DOMSource domSource = new DOMSource(doc);
    // use System.out for testing
    final StreamResult streamResult = new StreamResult(System.out);
    final TransformerFactory tf = TransformerFactory.newInstance();
    final Transformer serializer = tf.newTransformer();
    serializer.transform(domSource, streamResult);
    

    其中 jaxbContext 是您正在使用的 JAXBContext 对象,而 jaxbObject 是要编组的对象。此示例只是将注释附加到文档的末尾。对于不同的位置,您必须通过 doc 对象遍历 DOM,或者使用 XPath 找到您想要添加注释的确切元素并在其上使用 appendChild。

    【讨论】:

      猜你喜欢
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2011-04-09
      相关资源
      最近更新 更多