I have an xml document with separators deep down in the hierarchy.
<A>
<B>
<C id='1'/>
<separator/>
<C id='2'/>
</B>
<B>
<C id='3'/>
<separator/>
</B>
<B>
<C id='4'/>
</B>
</A>
I want to move the separators upwards, keeping elements in order. So the desired output is
<A>
<B>
<C id='1'/>
</B>
</A>
<separator/>
<A>
<B>
<C id='2'/>
</B>
<B>
<C id='3'/>
</B>
</A>
<separator/>
<A>
<B>
<C id='4'/>
</B>
</A>
How can it be done using xslt 1.0 only? Can it be done without for-each
, using template match only?
UPDATE: I actually got 4 brilliant answers of different levels of generality, thank you, guys.
This stylesheet:
Output:
Note: Grouping by following
separator
, adding last third level element for posibleC
without followingseparator
.Edit: More pull style, more schema agnostic, this stylesheet:
EDIT 2: More general solution (one thing I do not trust, ja!)
Note: Mostly a fine grained traversal. A floor hierarchy rule (in this case root element) copying itself and separator (dummy node for last group without following separator) passing remainder separators to process first child with enough following separators to process. A modified fine grained traversal identity rule, copying itself and again processing first child and following sibling with enough following separators to process. At last, a separator rule breaking the process.
Edit 3: Other more general solution, now with recursive identity rule
Edit 4: Now just the same as before but with key test instead of node set intersection.
This transformation:
when applied on the provided XML document:
produces the wanted, correct result: