I have an XML document that has several <item> elements. Inside each, there might be one or more of the following elements: <list>, <listAfter>, and <listBefore>. So, ignoring a lot of the extraneous elements, it might look like this:
<items>
<item>
<!-- ... various elements ... -->
<list>Enhancements</list>
</item>
<item>
<!-- ... various elements ... -->
<listBefore>Enhancements</listBefore>
<listAfter>Bugs</listAfter>
</item>
<item>
<!-- ... various elements ... -->
<list>Enhancements</list>
<listAfter>Next Release</listAfter>
</item>
<item>
<!-- ... various elements ... -->
<listBefore>Bugs</listBefore>
</item>
<item>
<!-- ... various elements ... -->
</item>
</items>
I want to remove all of the extraneous <list*> elements and have one <list> element per <item>. That element’s value should follow this logic:
- Use the value of
<list>if it’s available. - Otherwise, use the value of
<listAfter>if it’s available. - Otherwise, use the value of
<listBefore>if it’s available. - If none of these fields exist, use
No Listas the value.
Using my XML document above, here’s what I would expect the output to look like:
<items>
<item>
<!-- ... various elements ... -->
<list>Enhancements</list>
</item>
<item>
<!-- ... various elements ... -->
<list>Bugs</list>
</item>
<item>
<!-- ... various elements ... -->
<list>Enhancements</list>
</item>
<item>
<!-- ... various elements ... -->
<list>Bugs</list>
</item>
<item>
<!-- ... various elements ... -->
<list>No List</list>
</item>
</items>
Other than using the Identity Transform to copy over all other elements, I’m not sure how to include this logic in a nice manner. As always, your help is much appreciated.
You could do this by overriding the identity template, and adding extra templates to match the criteria for the various list elements.
To match listAfter you wish to include in the output, you would do the following (i.e listAfter elements with no list element as a sibling)
For the listBefore, you need to match them only if they have neither list not listAfter elements as siblings
In other cases, you would ignore listAfter and listBefore elements:
Finally, you can match item elements with none of the various list elements as children like so:
So, given the following XSLT:
When this is applied to your source XML, the following is output: