Reputation: 23
Given XML
<SystemInfo>
<Info>
<Name>ABC</Name>
<ID>ZZ</ID>
<Number>2332</Number>
<Date>2020-10-10</Date>
<Version>1.0</Version>
</Info>
<Info>
<Name>XYZ</Name>
<ID>ZZ</ID>
<Number>1234</Number>
<Date>2020-10-10</Date>
<Ind>X</Ind>
</Info>
<Info>
<Name>PQR</Name>
<ID>ZZ</ID>
<Number>1234</Number>
<Date>2020-10-10</Date>
<Ack>Y</Ack>
</Info>
</SystemInfo>
The XSLT should add a new element as the last element of 'Info' tag only when Name = 'XYZ' The expected output is as below.
<SystemInfo>
<Info>
<Name>ABC</Name>
<ID>ZZ</ID>
<Number>2332</Number>
<Date>2020-10-10</Date>
<Version>1.0</Version>
</Info>
<Info>
<Name>XYZ</Name>
<ID>ZZ</ID>
<Number>1234</Number>
<Date>2020-10-10</Date>
<Ind>X</Ind>
**<Type>P</Type>**
</Info>
<Info>
<Name>PQR</Name>
<ID>ZZ</ID>
<Number>1234</Number>
<Date>2020-10-10</Date>
<Ack>Y</Ack>
</Info>
</SystemInfo>
I tried the below two ways.
First implementation.
<xsl:template match="/|@*|node()">
<xsl:copy>
<xsl:apply-template select = "@*/node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="ns0:Info[./ns0:Name='XYZ']">
<xsl:apply-template select = "@*/node()" />
<xsl:element name="Type">P</xsl:element>
</xsl:template>
--> Result >> misses the 'Info' tag when Name='XYZ'
Second implementation.
<xsl:template match="/|@*|node()">
<xsl:copy>
<xsl:apply-template select = "@*/node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="ns0:Info[./ns0:Name='XYZ']">
<xsl:copy-of select = "." />
<xsl:element name="Type">P</xsl:element>
</xsl:template>
--> Result >> 'Type' shows up below the 'Info' end-tag instead of above the end-tag
Thanks in advance for the help
Upvotes: 1
Views: 444
Reputation: 29022
You only have to make minor changes to your template:
<xsl:template match="Info[Name='XYZ']">
<xsl:copy>
<xsl:apply-templates select = "@* | node()" />
<xsl:element name="Type">P</xsl:element>
</xsl:copy>
</xsl:template>
If necessary, add the namespace ns0:
to your match rule like this:
<xsl:template match="ns0:Info[ns0:Name='XYZ']">
...
And pay attention to the fact that your Identity template is incorrect. The correct one is the following:
<!-- Identity template -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
Its output is:
<?xml version="1.0"?>
<SystemInfo>
<Info>
<Name>ABC</Name>
<ID>ZZ</ID>
<Number>2332</Number>
<Date>2020-10-10</Date>
<Version>1.0</Version>
</Info>
<Info>
<Name>XYZ</Name>
<ID>ZZ</ID>
<Number>1234</Number>
<Date>2020-10-10</Date>
<Ind>X</Ind>
<Type>P</Type> <!-- Added by template -->
</Info>
<Info>
<Name>PQR</Name>
<ID>ZZ</ID>
<Number>1234</Number>
<Date>2020-10-10</Date>
<Ack>Y</Ack>
</Info>
</SystemInfo>
Upvotes: 1