Order of XML attributes after DOM processing

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 ?”.

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

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*>.

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} .../>

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.

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.

Hope this helps 😉

Leave a Comment