Reputation: 3
We have a current system that outputs an XML file which is in the following format:
<ResultSet rowCount="2">
<Row>
<Entry>83708</Entry>
<mark>L24653338N1</mark>
<Processed>NO</Processed>
</Row>
<Row>
<Entry>99999</Entry>
<mark>L24653338N1</mark>
<Processed>YES</Processed>
</Row>
</ResultSet>
I need to transform into:
<ResultSet rowCount="2">
<Row Processed="NO">
<Entry>83708</Entry>
<mark>L24653338N1</mark>
<Processed>NO</Processed>
</Row>
<Row Processed="YES">
<Entry>99999</Entry>
<mark>L24653338N1</mark>
<Processed>YES</Processed>
</Row>
</ResultSet>
Does someone know how this can be done using .XSL?
Here is what I have done:
</xsl:template>
<xsl:template name="transform">
<Row>
<xsl:if test="$linecount>0">
<xsl:for-each select="/Msg/Body/Payload[./@Role='S']/Msg/Body/Payload[./@sql]/SqlResult/ResultSet/Row">
<xsl:attribute name="pos"><xsl:value-of select="position()"/></xsl:attribute>
<Entry>
<xsl:value-of select="./Entry"/>
</Entry>
<mark>
<xsl:value-of select="./mark"/>
</mark>
<Proccessed>
<xsl:value-of select="./Proccessed"/>
</Proccessed>
</xsl:for-each>
</xsl:if>
</Row>
</xsl:template>
Upvotes: 0
Views: 142
Reputation: 70648
In tasks such as these, where you are only making changing to part of the XML, the usual approach is to start with the Identity Transform
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
On its own it will copy all the nodes and attributes as-is, so you only need to write templates for the things you wish to change. In your case you are adding a new Processed
attribute onto the Row
element. This means you only need a template that matches the Row
element that then adds this attribute, like so
<xsl:template match="Row">
<Row Processed="{Processed}">
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
Notice the use of Attribute Value Templates in the attribute you are creating. The curly braces {}
indicate an expression to be evalualted, not output literally, and so the value of the attribute will actually be the value of the Processed
element.
Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="Row">
<Row Processed="{Processed}">
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Note that you call also create attributes with xsl:attribute. For example
<xsl:template match="Row">
<Row>
<xsl:attribute name="Processed">
<xsl:value-of select="Processed" />
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</Row>
</xsl:template>
But as you can see, this is more verbose, so Attribute Value Templates are preferred where possible.
Upvotes: 1