在使用Java解析时如何在文档元素之前保留空格?

时间:2009-05-15 14:08:06

标签: java xml dom parsing whitespace

在我的应用程序中,我改变了一些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的一部分,但这不是问题。)

5 个答案:

答案 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,也不会与其他应用程序兼容。