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

Jen*_*ann 8 java xml whitespace parsing dom

在我的应用程序中,我修改了XML文件的一部分,其开头如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: version control yadda-yadda $ -->

<myElement>
...
Run Code Online (Sandbox Code Playgroud)

请注意之前的空白行<myElement>.加载,更改和保存后,结果远非令人满意:

<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: version control yadda-yadda $ --><myElement>
...
Run Code Online (Sandbox Code Playgroud)

我发现注释和文档节点之间的空白(一个换行符)根本没有在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/>
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何避免这种情况?基本上,我希望输出与输入相同.(我知道xml声明将被重新生成,因为它不是DOM的一部分,但这不是问题.)

Aar*_*lla 6

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

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

 <element
     attr="some complex value"
     />
Run Code Online (Sandbox Code Playgroud)

然后你可以.


McD*_*ell 3

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

Document -- 
    Element (maximum of one),
    ProcessingInstruction,
    Comment,
    DocumentType (maximum of one)
Run Code Online (Sandbox Code Playgroud)

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