I need to transform xml data into a different format. I have done very little XSL stuff and my internet search didn’t quite give me needed results. I have this sample xml:
<MailStatusReport>
<Output>
<ColMetaData ColCount="5">
<ColList>
<Col Name="parcelid" Pos="1"/>
<Col Name="currentlocationid" Pos="2"/>
<Col Name="deliverystatus" Pos="4"/>
<Col Name="requestedlocationid" Pos="3"/>
<Col Name="requestor" Pos="5"/>
</ColList>
</ColMetaData>
<RowList>
<Row>
<ColList>
<Col Pos="2">Delaware</Col>
<Col Pos="1">001</Col>
<Col Pos="3">NewYork</Col>
<Col Pos="4">InRoute</Col>
<Col Pos="5">John</Col>
</ColList>
</Row>
<Row>
<ColList>
<Col Pos="1">002</Col>
<Col Pos="2">Sanjose</Col>
<Col Pos="3">Michigan</Col>
<Col Pos="4">Delivered</Col>
<Col Pos="5">Rob</Col>
</ColList>
</Row>
</RowList>
</Output>
</MailStatusReport>
Desired output:
<MailStatusReport>
<Row parcelid="001" currentlocationid="Delaware" requestedlocationid="NewYork" deliverystatus="InRoute" requestor="John"/>
<Row parcelid="002" currentlocationid="Sanjose" requestedlocationid="Michigan" deliverystatus="Delivered" requestor="Rob"/>
</MailStatusReport>
Few things to note:
- The Name attribute of ColMetaData/ColList/Col in the input xml ends up as an attribute name for each Row element of the output xml.
- The value of RowList/Row/ColList/Col in the input xml ends up as the attribute value in the output xml for the attribute which has the same Pos as in the ColMetaData/ColList/Col section.
- ColCount attribute of ColMetaData is trust worthy and could be used as a counter if needed.
The Pseudo code I could think of would be:
For each CurrentRow in the RowList
Begin Building OutputRow
For each Col in ColMetaData/ColList
attrName = ColMetaData/ColList/Col/Name
attrPos = ColMetaData/ColList/Col/Pos
attrVal = CurrentRow/ColList/Col[@Pos=$attrPos]
Add $attrName=$attrVal to the outputRow
I would appreciate any help that I could get!
Thanks
Srinivas
This transformation:
when applied on the provided XML document:
produces the wanted, correct result:
Explanation:
Using
<xsl:sort>for ordering the results of the attributes generation.Using
<xsl:key>and thekey()function to define a mapping between column name and column position — for more convenient calculating the name of the attribute that is being generated.Producing the name of attributes from calculated values using AVT (Attribute Value Template).