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

使用Java解析时,如何在文档元素之前保留空格?,java,xml,dom,parsing,whitespace,Java,Xml,Dom,Parsing,Whitespace,在我的应用程序中,我更改了XML文件的某些部分,其开头如下: <?xml version="1.0" encoding="UTF-8"?> <!-- $Id: version control yadda-yadda $ --> <myElement> ... <element attr="some complex value" /> ... 注意 >代码>之前的空白行。在加载、更改和保存后,结果远远不令人满意: &l

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

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

<myElement>
...
 <element
     attr="some complex value"
     />

...

注意<代码> >代码>之前的空白行。在加载、更改和保存后,结果远远不令人满意:

<?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/>
字符串源=
“\n\n”;
byte[]sourceBytes=source.getBytes(“UTF-16”);
文档生成器=
DocumentBuilderFactory.newInstance().newDocumentBuilder();
文件文件=
parse(新的ByteInputStream(sourceBytes,sourceBytes.length));
dominimplementals dominimplementals=
(DomImplementals)doc.getImplementation();
LSSerializer LSSerializer=doimplementation.createLSSerializer();
System.out.println(lsSerializer.writeToString(doc));
//输出:\n

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

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

为什么要避免这样

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

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


如果你正在开发依赖于这条空行的东西。。。不要。我也有同样的问题。我的解决方案是编写自己的XML解析器:

主要特点:它可以100%保留原始输入,空白,实体,一切。详细信息不会影响您,但如果您的代码需要生成如下XML:

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

<myElement>
...
 <element
     attr="some complex value"
     />


P.>我同意克里斯和托马拉克,空白行与XML观点无关。如果您的应用程序需要在输出中生成一个空行,我建议您检查该要求的需要

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

  • 检查org.dom4j.io.DOMWriter

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

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

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

关键是原始输入中有一行,应该保留它-文档其余部分中的所有空白都是如此!当然,没有任何程序依赖这种格式。但是,这些文件包含翻译数据;它们被签入到版本控制并持续维护。因此,如果我的应用程序所做的唯一更改是有意更改,那么查看差异就更好了。。。我认为处理这个问题的唯一明智的方法是不要在文件中留下这一空行。我认为没有任何值得推荐的方法来保留这条线。也许文件在签入之前通常应该通过一个整理工具传递,以避免这些不一致。@Tomalak::你能帮我吗:谢谢你的建议;DecentXML看起来确实是一件需要记住的好事情!很高兴看到至少有一个“又一个解析器”项目有一个存在的真正理由。但是,对于我目前的问题,我更愿意在整个处理代码中使用标准的DOM API,只需在输出阶段添加行即可,然后需要在根元素之前手动添加文本节点。查看文档对象如何添加普通(非元素)节点。如果这不可能,您必须为写入器/输出流创建一个过滤器,该过滤器会对其中的换行符进行黑客攻击。@Aarondigula::您能帮助我吗?我最后使用一个自定义OutputStream类将其黑客攻击到输出中,该类会查找“-->我也有同样的问题。你能帮我一下吗?答案很好,但在我看来,这是规范中一个愚蠢的错误。您当然可以在document元素之前输出文本,但您不能输入它?@McDowell我们可以做些什么来避免这种情况,请查看我的问题。那么打算由人类编辑的XML文件呢?在这种情况下,原始格式很重要。XML不仅用于序列化,如果是二进制格式就更好了。