xml-parsing - 使用 StAXResult 调用 Transformer 时省略 XML 声明

标签 xml-parsing stax transformer-model

我想将多个 XML 节点从源 XML 文件复制到目标文件。源文件和目标文件都非常大,所以我将使用 StAX。通常,我尝试处理的文件如下所示:

<root>
  <header>
    <title>A List of persons</title>
  </header>
  <person>
    <name>Joe</name>
    <surname>Bloggs</surname>
  </person>  
  <person>
    <name>John</name>
    <surname>Doe</surname>
  </person>  
  .
  .
  etc...
</root>

目标文件应采用以下格式:

<root>
  <header>
    <title>A List of persons</title>
  </header>
  <person>
    <name>Joe</name>
    <surname>Bloggs</surname>
  </person>
</root>

其中每个文件应包含 header 节点,恰好有一个 person 节点,全部包含在 root 节点内。

现在我的问题如下:我尝试通过 XMLStreamReader 读取源文件,并使用 XMLStreamWriter 写入它,这两个文件都连接到复制片段的 Transformer 实例中从源文件到目标文件。变压器创建如下:

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

StAXSource stAXSource = new StAXSource(reader);
StAXResult stAXResult = new StAXResult(writer);

我还有一个自定义方法,可将光标移动到 XML 输入流中所需的片段:

// Moves XMLStreamReader cursor to the next fragment. 
moveCursorToNextFragment(XMLStreamReader reader, String fragmentNodeName)

所以最终我得到以下结果:

// Open file as usual...

// Advance cursor to <header> node, and copy fragment till
// </header> to the output writer. 
moveCursorToNextFragment(reader, "header");
transformer.transform(stAXSource, stAXResult);

// Advance cursor to <person> node, and copy fragment till
// </person> to the output writer.
moveCursorToNextFragment(reader, "person");
transformer.transform(stAXSource, stAXResult);

问题是生成的 XML 文件包含 2 个 XML 声明部分,每次调用一个

transformer.transform(stAXSource, stAXResult);

我尝试使用StreamResult来转换输出,如下所示:

transformer.transform(stAXSource, new StreamResult(myStream));

并且 XML 声明被省略,但是当我恢复使用 StAXResult 时,XML 声明又回来了。我还注意到,OutputKeys.OMIT_XML_DECLARATION 无论打开还是关闭都没有任何影响(其他设置如 OutputKeys.STANDALONE 的值为“yes”)。

简而言之,当 StAXResult 作为目标结果时,在 Transformer 上全局设置的这些设置似乎被忽略。

我的问题是:有什么方法可以实现这一点,以便 Transformer 在每次调用 Transformer.transform() 时不会发出 XML 声明(即写入没有 XML 声明的片段)?

非常感谢并需要您的帮助。

最佳答案

Xalan 的 SAX2StAXStreamWriter 正在执行此操作。另一个 XSLT 实现的行为可能有所不同。为了解决这个问题,您可以包装您的编写器并强制 startDocument(...) 方法不执行任何操作。 StAXON图书馆提供 StreamWriterDelegate实用程序类有助于保持必要的代码简短:

writer = new StreamWriterDelegate(writer) {
  @Override public void writeStartDocument() {}
  @Override public void writeStartDocument(String version) {}
  @Override public void writeStartDocument(String encoding, String version) {}
};

应该可以解决问题。

关于xml-parsing - 使用 StAXResult 调用 Transformer 时省略 XML 声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9598345/

相关文章:

java - 从 https 调用 Web 服务并用 Java 解析响应的 xml 数据

ios - 无法在容器 View 中加载 xml 数据

javascript - 尝试使用 DOMParser 解析 html 字符串时出现问题

c# - 编写 xml 并将其读回 c#

java - 使用 OutputStreamWriter(StAX 解析器)将数据附加到 XML 文件

nlp - 如何在batch_encode_plus之后获得一批句子的翻译?

tokenize - 属性错误 : 'GPT2TokenizerFast' object has no attribute 'max_len'

java - StAXON - 当 autoPrimitive 为 true 时,强制将特定值设置为 String

带有 cxf : Soap11FaultInInterceptor. unmarshalFault 的 soap 客户端

java标准库产生错误的xml 1.1