我想将多个 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>
每个文件都应该包含头节点,恰好一个人节点都包含在根节点中。
现在我的问题如下:我试图通过 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 声明的片段)?
非常感谢和需要您的帮助。