I would like to know how to use xsl templates to transform my xml document to another xml document with original element hierarchy. I would also like to add some attributes to elements in the new generated XML.
My original XML file looks something like this:
<shop>
<product>
<cookie ID="001">
<price>2</price>
</cookie>
</product>
<product>
<bread ID="002">
<price>5</price>
</bread>
</product>
<product>
<milk ID="003">
<price>2</price>
</milk>
</product>
</shop>
I would like to transform this to following XML:
<newXML>
<newElement>
<newElement ID="001">
<newElement price="2"/>
</newElement>
</newElement>
<newElement>
<newElement ID="002">
<newElement price="5"/>
</newElement>
</newElement>
<newElement>
<newElement ID="003">
<newElement price="2"/>
</newElement>
</newElement>
</newXML>
What would be a good way to do this? Can this be done using recursion with templates or is there some better way? I’ve been trying to use following logic:
- make a template that creates an element
- read current elements ID if it exist and put it to newElement
- if current element has a child, apply this template to it (some kind of recursion)
Despite of many attempts I haven’t been able to make this work. Your help would be greatly appreciated!
To do this, you would build upon the XSLT Identity Transform, which is a very common design pattern in XSLT. To start with you just have a template that copies the elements and outputs them exactly as-is]
What you then do is add extra templates to match your elements, and add codes to rename them, or add attributes as required. For example, to rename the root element you would add the following template:
You don’t have to use specific element names here either. If you wanted to rename and element with an ID attribute to the same name, you could do something like this
And in the case of your price element, if you wanted to create an attribute based on the element’s text content, you could add a template like so:
(Note, this uses Attribute Value Templates to create the attribute here. THis is usually preferred to using xsl:attribute)
Try this XML for starters:
This outputs the following: