views:

899

answers:

4

I would like to control the attribute order in .java files generated by the JAXB compiler.

I'm aware that attribute order is not important for xml validation. The order is important for textual comparison of marshalled xml in a regression test environment. The order of attributes in a file directly affects the order of the attributes in marshalled xml tags.

Every time the JAXB compiler is run attribute groups appear in a different order, even with no changes to the schema. There is no apparent option available on the compiler to prevent this behavior.

I would like to avoid running a post-compilation script to alphabetically reorder attributes in the generated .java files since this breaks up the attribute groups, but I'm not sure there is another option.

Any suggestions are much appreciated.

Thanks, Dave

+1  A: 

I'd recommend using an XML parser to validate the output instead of doing textual comparisons. If you're going to be parsing the xml to re-order it anyway, you may as well just do the comparison using XML tools.

Edit: Attempting to control the generated XML by manipulating the Java source code order seems like a fragile way of doing things. Granted, this is for testing only, so if something breaks the code might still work properly. People change source code order all the time, sometimes by accident, and it will be annoying or a subtle source of problems if you have to rely on a certain ordering.

As for ways of comparing the XML data using XML tools, I've never personally done this on a large scale, but this link mentions a few free tools. For me the extension to JUnit that provides XML-related assertions would be my first step, as that could integrate well with my existing tests. Otherwise, since you're mainly looking for exact equivalence, you could just parse the two XML files, then iterate over the nodes in the 'expected' file and see if those nodes are present in the 'actual' file. Then just check for any other nodes that you don't expect to see.

Mr. Shiny and New
The comparison is part of a large bash script driven regression test and we are not currently parsing any of the xml responses. I could use an XML diff tool but I don't have any experience with them. I am working in a Solaris environment - can you suggest a xml diff tool that can be invoked from the command line for this purpose?Also the files to be compared may not validate against the schema because certain known differences are substituted with constant values.
daveg
Additionally I was considering re-ordering the attributes in the .java file - not the xml response. I guess the marshaller uses reflection because the order in the .java file seems to directly control the attribute order in the marshalled responses.
daveg
I edited my answer to address your two points.
Mr. Shiny and New
The JAXB compiler output is conveniently labeled with a "@XmlAttribute" annotation before each attribute declaration in the source. It seems fairly doable to write a reliable perl filter to reorder those declarations, but I agree it's a hacky (and likely fragile) solution.Anyway thanks for the link - hopefully one of these tools will provide a relatively cheap solution.
daveg
+1  A: 

If you need to perform textual comparison of XML documents, there are better ways of doing it than by trying to control the output of an XML framework that does not distinguish between attribute ordering.

For example, there's XMLUnit, which is a junit extension specifically for XML assertions, and it handles whitespace and ordering quite nicely.

A more general solution is XOM's Canonicalizer, which outputs XML DOMs such that the attribute ordering and whitespace is predictable. Very handy.

So... let JAXB (or whatever) generate the XML as it sees fit, then run the outputs through XMLUnit or XOM, and compare. This has the added advantage of not depending on JAXB, it'll work with any generated XML.

skaffman
A: 

This thread provides a great solution to my problem.

http://stackoverflow.com/questions/1429991/using-xsl-to-sort-attributes

One of the answers contains a xsl transform that just reorders the attributes. Works perfectly if a little slow.

daveg
+1  A: 

Apparently, in JAXB 2.0 you can use the annotation @XmlAccessorOrder or @XmlType(propOrder=)

Juan Domínguez