Is there any way to reorder elements in a Node objects such that they match an xsd:sequence
order? I\'ve read through the docs for Node.normalize
, but
If you only have xs:sequence to worry about, and not choice/repetition, and so long as the schema isn't written to use lots of complex features like named model groups and substitution groups and wildcards, then it shouldn't be too difficult, at any rate if you use XSLT 2.0 or XQuery and forget about trying to code it in Java. If the variable $seq is an xs:sequence element, then the sort key for an element named $E is "count($x/xs:element[(@name|@ref)=$E]/preceding-sibling::*", so you can just plug this expression into an xsl:sort as
<xsl:for-each select="*">
<xsl:sort select="count($seq/xs:element[(@name|@ref)=local-name(current())]/preceding-sibling::*"/>
...
</xsl:for-each>
Probably needs a bit of finessing for namespaces or other things you might encounter, but you get the idea.
You can manipulate XML directly in Java using the following packages:
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
You'll need to put an XML parser such as saxon ( see http://saxon.sourceforge.net/ ) on your classpath
You can manipulate the XML 'by hand', reading bits of the input document and creating the required output document or you can write an xslt style sheet and use it to transform the document straight from your Java code.
Try here for a starting point:
http://oreilly.com/catalog/javaxslt/chapter/ch05.html
If I read your question correctly, what you want is rather a "magical" (as in a simple) way of getting nodes re-arranged according to an external XSD, as opposed to a way to move nodes around using some XML API.
If true, then I am not aware of any API that provides a generic way to achieve such a thing. It is also not a trivial piece of programming, given the complexity of the content models XSD is able to describe.
It is also, under very simple circumstances, virtually impossible to solve. Think of this very simple example: imagine a content model made up of two choices, i) sequence a - b - c , ii) sequence b - c - a. The XML content comes in the order c - b - a (as per your requirement, you want to take in invalid XML, and make it valid). In this example, which is the right way to do it?
Of course, I am not saying this is your scenario. I am simply trying to point out why no one, as far as I know, has come up with a solution to such a problem.
If your content model under the sequence is rather trivial, thus allowing for an unambiguous way of solving it irrespective of the sequence in which your XML arrives, or if the XML content comes in a known, but wrong way, all the time, then you have to code it using your preferred approach to XML manipulation - but I would suggest, don't try to make it generic, it is just going down the rabbit hole ;)....