在我的应用程序中,我改变了一些XML文件,它们是这样开始的:
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: version control yadda-yadda $ -->
<myElement>
...
请注意<myElement>
之前的空白行。在加载,更改和保存之后,结果远非令人满意:
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: version control yadda-yadda $ --><myElement>
...
我发现注释和文档节点之间的空白(一个换行符)根本没有在DOM中表示。以下自包含代码可靠地再现了该问题:
String source =
"<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<!-- foo -->\n<empty/>";
byte[] sourceBytes = source.getBytes("UTF-16");
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc =
builder.parse(new ByteInputStream(sourceBytes, sourceBytes.length));
DOMImplementationLS domImplementation =
(DOMImplementationLS) doc.getImplementation();
LSSerializer lsSerializer = domImplementation.createLSSerializer();
System.out.println(lsSerializer.writeToString(doc));
// output: <?xml version="1.0" encoding="UTF-16"?>\n<!-- foo --><empty/>
有没有人知道如何避免这种情况?基本上,我希望输出与输入相同。 (我知道xml声明将被重新生成,因为它不是DOM的一部分,但这不是问题。)
答案 0 :(得分:6)
我遇到了同样的问题。我的解决方案是编写自己的XML解析器:DecentXML
主要特点:它可以100%保留原始输入,空白,实体,一切。它不会打扰你的细节,但如果你的代码需要像这样生成XML:
<element
attr="some complex value"
/>
那么你可以。
答案 1 :(得分:3)
为什么要避免这种情况?
标签/元素之外的空白区域被规范定义为无关紧要。它只是不存在,只要涉及由你的DOM代表的信息集。
因此,在再次序列化DOM时,它不会存在。
如果你正在开发依赖这条空行的东西......不要。
答案 2 :(得分:2)
根本原因是标准DOM Level 3无法在不破坏规范的情况下将Text节点表示为Document的子节点。任何兼容的解析器都会删除空格。
Document --
Element (maximum of one),
ProcessingInstruction,
Comment,
DocumentType (maximum of one)
如果您需要符合标准的解决方案且目标是可读性而不是100%再现,我会在您的输出机制中寻找它。
答案 3 :(得分:1)
通常,在XML中,空格被认为是不相关的,因此在解析XML文件时不会保留空格。大多数输出XML的库都有一个输出选项,可以输出格式和正确的缩进,但它总是相当通用的。没有“在这里有额外的行”。
答案 4 :(得分:0)
我同意Kris和Tomalak的观点,从XML的角度来看,空白行是不相关的。如果您的应用程序需要在输出中生成一个空行,我建议您查看该要求的必要性。
无论如何,如果您仍然希望显示该空白行,我建议您下载正在使用的XML解析器的源代码并修改该行为。但请记住,这不是标准的XML,也不会与其他应用程序兼容。