DOM 处理后 XML 属性的顺序 [英] Order of XML attributes after DOM processing

查看:21
本文介绍了DOM 处理后 XML 属性的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用标准DOM处理XML时,序列化回后无法保证属性顺序.最后这就是我在使用标准 java XML Transform API 序列化输出时才意识到的.

When processing XML by means of standard DOM, attribute order is not guaranteed after you serialize back. At last that is what I just realized when using standard java XML Transform API to serialize the output.

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

However I do need to keep an order. I would like to know if there is any posibility on Java to keep the original order of attributes of an XML file processed by means of DOM API, or any way to force the order (maybe by using an alternative serialization API that lets you set this kind of property). In my case processing reduces to alter the value of some attributes (not all) of a sequence of the same elements with a bunch of attributes, and maybe insert a few more elements.

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

Is there any "easy" way or do I have to define my own XSLT transformation stylesheet to specify the output and altering the whole input XML file?

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

Update I must thank all your answers. The answer seems now more obvious than I expected. I never paid any attention to attribute order, since I had never needed it before.

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

The main reason to require an attribute order is that the resulting XML file just looks different. The target is a configuration file that holds hundreds of alarms (every alarm is defined by a set of attributes). This file usually has little modifications over time, but it is convenient to keep it ordered, since when we need to modify something it is edited by hand. Now and then some projects need light modifications of this file, such as setting one of the attributes to a customer specific code.

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

I just developed a little application to merge original file (common to all projects) with specific parts of each project (modify the value of some attributes), so project-specific file gets the updates of the base one (new alarm definitions or some attribute values bugfixes). My main motivation to require ordered attributes is to be able to check the output of the application againts the original file by means of a text comparation tool (such as Winmerge). If the format (mainly attribute order) remains the same, the differences can be easily spotted.

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

I really thought this was possible, since XML handling programs, such as XML Spy, lets you edit XML files and apply some ordering (grid mode). Maybe my only choice is to use one of these programs to manually modify the output file.

推荐答案

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

Sorry to say, but the answer is more subtle than "No you can't" or "Why do you need to do this in the first place ?".

简短的回答是DOM 不允许你这样做,但 SAX 会".

The short answer is "DOM will not allow you to do that, but SAX will".

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

This is because DOM does not care about the attribute order, since it's meaningless as far as the standard is concerned, and by the time the XSL gets hold of the input stream, the info is already lost. Most XSL engine will actually gracefully preserve the input stream attribute order (e.g. Xalan-C (except in one case) or Xalan-J (always)). Especially if you use <xsl:copy*>.

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

Cases where the attribute order is not kept, best of my knowledge, are. - If the input stream is a DOM - Xalan-C: if you insert your result-tree tags literally (e.g. <elem att1={@att1} .../>

这里是一个使用 SAX 的例子,作为记录(也抑制 DTD 唠叨).

Here is one example with SAX, for the record (inhibiting DTD nagging as well).

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 );

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

I'd also like to point out, at the intention of many naysayers that there are cases where attribute order does matter.

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

Regression testing is an obvious case. Whoever has been called to optimise not-so-well written XSL knows that you usually want to make sure that "new" result trees are similar or identical to the "old" ones. And when the result tree are around one million lines, XML diff tools prove too unwieldy... In these cases, preserving attribute order is of great help.

希望这有帮助;-)

这篇关于DOM 处理后 XML 属性的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆