java - DOM 处理后的 XML 属性顺序

标签 java xml dom

当通过标准 DOM 处理 XML 时,在序列化后不能保证属性顺序。最后,这就是我在使用标准 java XML Transform API 序列化输出时才意识到的。

但是我确实需要保持订单。我想知道Java是否有任何可能性来保持通过DOM API处理的XML文件属性的原始顺序,或者任何强制顺序的方式(也许通过使用允许您设置的替代序列化API种属性)。在我的情况下,处理减少以改变具有一堆属性的相同元素序列的某些属性(不是全部)的值,并且可能插入更多元素。

是否有任何“简单”的方法,或者我必须定义自己的 XSLT 转换样式表来指定输出并更改整个输入 XML 文件?

更新我必须感谢您的所有回答。答案现在似乎比我预期的更明显。我从来没有关注过属性顺序,因为我以前从来不需要它。

需要属性顺序的主要原因是生成的 XML 文件只是看起来不同。目标是一个包含数百个警报的配置文件(每个警报都由一组属性定义)。这个文件通常随着时间的推移几乎没有修改,但保持它的顺序很方便,因为当我们需要修改某些东西时,它是手动编辑的。有时,一些项目需要对该文件进行轻微修改,例如将属性之一设置为客户特定的代码。

我刚刚开发了一个小应用程序,将原始文件(所有项目通用)与每个项目的特定部分(修改某些属性的值)合并,因此项目特定文件获取基础文件的更新(新的警报定义或一些属性值错误修正)。我要求有序属性的主要动机是能够通过文本比较工具(例如 Winmerge)检查应用程序的输出与原始文件的对比。如果格式(主要是属性顺序)保持不变,则很容易发现差异。

我真的认为这是可能的,因为 XML 处理程序(例如 XML Spy)允许您编辑 XML 文件并应用一些排序(网格模式)。也许我唯一的选择是使用这些程序之一来手动修改输出文件。

最佳答案

很抱歉,但答案比“不,你不能”或“为什么你首先需要这样做?”更微妙。

简短的回答是“DOM 不允许您这样做,但 SAX 会”。

这是因为 DOM 不关心属性顺序,因为它就标准而言毫无意义,并且当 XSL 获取输入流时,信息已经丢失。 大多数 XSL 引擎实际上会优雅地保留输入流属性顺序(例如 Xalan-C(除了一种情况)或 Xalan-J(总是))。特别是如果您使用 <xsl:copy*> .

据我所知,不保留属性顺序的情况是。 - 如果输入流是 DOM - Xalan-C:如果您按字面意思插入结果树标签(例如 <elem att1={@att1} .../>

这里是一个 SAX 的例子,记录在案(也抑制 DTD 唠叨)。

SAXParserFactory spf = SAXParserFactoryImpl.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(false);
spf.setFeature("http://xml.org/sax/features/validation", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
SAXParser sp = spf.newSAXParser() ;
Source src = new SAXSource ( sp.getXMLReader(), new InputSource( input.getAbsolutePath() ) ) ;
String resultFileName = input.getAbsolutePath().replaceAll(".xml$", ".cooked.xml" ) ;
Result result = new StreamResult( new File (resultFileName) ) ;
TransformerFactory tf = TransformerFactory.newInstance();
Source xsltSource = new StreamSource( new File ( COOKER_XSL ) );
xsl = tf.newTransformer( xsltSource ) ;
xsl.setParameter( "srcDocumentName", input.getName() ) ;
xsl.setParameter( "srcDocumentPath", input.getAbsolutePath() ) ;

xsl.transform(src, result );

我还想指出,出于许多反对者的意图, 属性顺序确实 很重要。

回归测试是一个明显的例子。 任何被要求优化写得不太好的 XSL 的人都知道,您通常希望确保"new"结果树与“旧”结果树相似或相同。当结果树大约有一百万行时,XML diff 工具被证明太笨拙了...... 在这些情况下,保留属性顺序很有帮助。

希望这会有所帮助;-)

关于java - DOM 处理后的 XML 属性顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/726395/

相关文章:

java - 打印二叉树中从根到叶的所有路径

java - Netty 管道配置

android - Kotlin 中按钮状态的不同背景

java - 更改导航栏颜色,Android

java - 连接 SAX 检索到的两个字符串

javascript - 使用 selectAll() 到达特定类

jquery - 检查节点类型的图片/Alt 属性

Java - 反射 - 如何使用反射获取@RequestHeader值

java - Gradle 项目同步失败 - Android Studio 0.8.14

javascript - “dbclick”事件监听器不工作,但 'click' 正常