8

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

4

5 回答 5

6

我有同样的问题。我的解决方案是编写自己的 XML 解析器:DecentXML

主要特点:它可以 100% 保留原始输入,空白,实体,一切。它不会打扰您的细节,但如果您的代码需要像这样生成 XML:

 <element
     attr="some complex value"
     />

那么你就可以。

于 2009-05-15T14:33:05.330 回答
3

为什么要避免这种情况?

标签/元素之外的空白被规范定义为无关紧要的。它根本不存在,就您的 DOM 表示的信息集而言。

因此,在再次序列化 DOM 时,它将不存在。

如果您正在开发依赖于这个空行的东西......不要。

于 2009-05-15T14:15:15.060 回答
3

根本原因是标准DOM Level 3不能在不违反规范的情况下将 Text 节点表示为 Document 的子节点。任何兼容的解析器都会删除空格。

Document -- 
    Element (maximum of one),
    ProcessingInstruction,
    Comment,
    DocumentType (maximum of one)

如果您需要符合标准的解决方案,并且目标是可读性而不是 100% 复制,我会在您的输出机制中寻找它。

于 2009-05-15T15:43:44.800 回答
1

通常,空白在 XML 中被认为是不相关的,因此在解析 XML 文件时不会保留。大多数输出​​ XML 的库都可以选择以良好的格式和正确的缩进输出它,但它总是相当通用的。没有“这里有一个额外的行”。

于 2009-05-15T14:14:15.407 回答
0

我同意 Kris 和 Tomalak 的观点,从 XML 的角度来看,空行是不相关的。如果您的应用程序需要在输出中产生一个空行,我建议您查看该要求的需要。

无论如何,如果您仍然希望出现该空白行,我建议您下载您正在使用的 XML 解析器的源代码并修改该行为。但请记住,这不是标准 XML,它不会与其他应用程序兼容。

于 2009-05-15T14:33:49.273 回答