使用Java解析时如何在文档元素之前保留空格?
Posted
技术标签:
【中文标题】使用Java解析时如何在文档元素之前保留空格?【英文标题】:How to keep whitespace before document element when parsing with Java? 【发布时间】:2010-10-26 12:22:12 【问题描述】:在我的应用程序中,我更改了 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 的一部分,但这不是问题。)
【问题讨论】:
我最终使用自定义 OutputStream 类将其破解到输出中,该类查找“--> 我有同样的问题。你能帮忙吗? ***.com/questions/30940162/… 【参考方案1】:一般来说,空白在 XML 中被认为是不相关的,因此在解析 XML 文件时不会保留。大多数输出 XML 的库都可以选择以良好的格式和正确的缩进输出它,但它总是相当通用的。没有“在这里有一个额外的行”。
【讨论】:
关键是原始输入中有一行,应该保留 - 就像文档其余部分中的所有空白一样!跨度> 【参考方案2】:为什么要避免这种情况?
标签/元素之外的空白被规范定义为无关紧要。就您的 DOM 所代表的信息集而言,它根本不存在。
因此,在再次序列化 DOM 时,它将不存在。
如果您正在开发依赖于这个空行的东西......不要。
【讨论】:
当然,没有程序依赖这种格式。但是,这些文件包含翻译数据;它们被签入版本控制并持续维护。因此,如果我的应用所做的唯一更改是有意更改,那么查看差异会很好。 我是这么认为的...我认为唯一明智的处理方法是在文件中不要有这个空行。我认为没有任何可推荐的方法来保留这条线。也许文件应该在签入之前通过整理工具作为规则传递,以避免这些不一致。 @Tomalak::你能帮帮我吗:***.com/questions/30940162/…【参考方案3】:我遇到了同样的问题。我的解决方案是编写自己的 XML 解析器:DecentXML
主要特点:它可以 100% 保留原始输入,空白,实体,一切。它不会打扰你的细节,但如果你的代码需要像这样生成 XML:
<element
attr="some complex value"
/>
那么你就可以了。
【讨论】:
感谢您的建议; DecentXML 看起来确实是一件值得牢记的好东西! bookmarksIt 很高兴看到至少有一个“又一个解析器”项目有一个非常好的存在理由。但是,对于我当前的问题,我更愿意在整个处理代码中使用标准 DOM API,并在输出阶段简单地添加该行。 那么你需要在根元素之前手动添加文本节点。查看 Document 对象如何添加普通(非元素)节点。如果这不可能,您必须为写入器/输出流创建一个过滤器,该过滤器会破解其中的换行符。 @AaronDigulla::你能帮我解决这个问题吗***.com/questions/30940162/…【参考方案4】:我同意 Kris 和 Tomalak 的观点,从 XML 的角度来看,空行是不相关的。如果您的应用程序需要在输出中生成一个空行,我建议您查看该要求的需要。
无论如何,如果您仍然希望显示该空白行,我建议您下载您正在使用的 XML 解析器的源代码并修改该行为。但请记住,这不是标准 XML,它不会与其他应用程序兼容。
Jdom Source Dom4j Source检查org.dom4j.io.DOMWriter【讨论】:
那些打算由人类编辑的 XML 文件呢?在这种情况下,原始格式很重要。 XML不仅是为了序列化,如果是二进制格式会更好。【参考方案5】:根本原因是标准DOM Level 3 无法在不违反规范的情况下将文本节点表示为文档的子节点。任何兼容的解析器都会删除空格。
Document --
Element (maximum of one),
ProcessingInstruction,
Comment,
DocumentType (maximum of one)
如果您需要符合标准的解决方案并且目标是可读性而不是 100% 可复制,我会在您的输出机制中寻找它。
【讨论】:
很好的答案,但在我看来,这是规范中的一个愚蠢的错误。你当然可以在document元素之前输出文本,但是不能输入? @McDowell 我们可以做些什么来避免这种情况,请查看我的问题。 ***.com/questions/30940162/…以上是关于使用Java解析时如何在文档元素之前保留空格?的主要内容,如果未能解决你的问题,请参考以下文章