I need to translate an XML from the source format to the target name value pairs for generic processing. Any tips on how to achieve this please? I am trying to use MapForce if it's easier.
From
<products>
<product>
<type>Monitor</type>
<size>22</size>
<brand>EIZO</brand>
</product>
<product>
......
</product>
</products>
to
<products>
<product num="1">
<attribute name="type">Monitor</attribute>
<attribute name="size">22</attribute>
<attribute name="brand">EIZO</attribute>
</product>
<product num="2">
....
</product>
</products>
I presume I need to use xsl:for-each in the element to generate the element?
How about the "num" attribute, it's just a counter basically. could it be position()?
Many Thanks!!
For problems like this you often start off by building the XSLT identity template
On its own this copies all nodes as-is, which means you only need to write matching templates for nodes you wish to transform.
To start with, you wish to add the num attribute to the product, so have a template matching product where you simply output it with the attribute and continue processing its children.
Do note the use of Attribute Value Templates here in creating the num attribute. The curly braces indicate an expression to be evaluated, not output literally.
Then, you want a template to match the children of the product elements, and turn these into attribute nodes. This is done with a pattern to match any such child, like so
Note that
<xsl:apply-templates />
could be replaced with<xsl:value-of select="." />
here if you are only ever going to have text nodes within the child elements.Try this XSLT
When applied to your XML the following is output
Of course, if do actually want to turn the child elements into proper attributes, as opposed to elements named "attribute", you would use the xsl:attribute command. Replace the last template with this
When using this template instead, the following is output (Well, it would include product 2 if your sample has child elements for it!)