Reputation: 483
I have to add Element Main/Years/Year/Notification/@UniqueId="27"
& Main/Years/Year/@IsFailFlag = "Y"
, Only if Main/Years/Year/Month/Extn/@Flag !=''
.
and I have to copy Main/Years/Year/Month
for such cases.
XML
<?xml version="1.0" encoding="UTF-8"?>
<Main>
<Years>
<Year>
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="A" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="B" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
</Year>
</Years>
</Main>
My XSL
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<LoadShipment>
<xsl:for-each select="/Main/Years/Year/Month/Extn">
<xsl:if test="@Flag != ''">
<xsl:attribute name="IsFailFlag">
<xsl:value-of select="'Y'" />
</xsl:attribute>
<Notification>
<xsl:attribute name="UniqueId">
<xsl:value-of select="'27'" />
</xsl:attribute>
</Notification>
<xsl:copy-of select=".." />
</xsl:if>
</xsl:for-each>
</LoadShipment>
</xsl:template>
</xsl:stylesheet>
I am getting repeated Notification as its inside for loop and i cant move it out becuase then it will always get populated irrespective of the condition
Output
<?xml version="1.0" encoding="UTF-8"?>
<LoadShipment IsFailFlag="Y">
<Notification UniqueId="27" />
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="A" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
<Notification UniqueId="27" />
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="B" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
</LoadShipment>
Expected Output
<?xml version="1.0" encoding="UTF-8"?>
<LoadShipment IsFailFlag="Y">
<Notification UniqueId="27" />
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="A" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="B" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
</LoadShipment>
Upvotes: 0
Views: 131
Reputation: 101748
How's this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:variable name="badMonths"
select="Main/Years/Year/Month[Extn/@Flag != '']" />
<LoadShipment>
<xsl:if test="$badMonths">
<xsl:attribute name="IsFailFlag">Y</xsl:attribute>
<Notification UniqueId="27" />
<xsl:copy-of select="$badMonths" />
</xsl:if>
</LoadShipment>
</xsl:template>
</xsl:stylesheet>
When run on your sample input, the result is:
<LoadShipment IsFailFlag="Y">
<Notification UniqueId="27" />
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="A" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
<Month ActualDate="" Type="C" FailText="">
<Extn Flag="B" />
<Details>
<Line A="a" B="3" C="1" />
</Details>
</Month>
</LoadShipment>
Or a different approach that's a little more "XSLT-esque" (same result):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:variable name="badMonths"
select="Years/Year/Month[Extn/@Flag != '']" />
<LoadShipment>
<xsl:apply-templates select="(.)[$badMonths]" mode="failed" />
<xsl:apply-templates select="$badMonths" />
</LoadShipment>
</xsl:template>
<xsl:template match="*" mode="failed">
<xsl:attribute name="IsFailFlag">Y</xsl:attribute>
<Notification UniqueId="27" />
</xsl:template>
</xsl:stylesheet>
Upvotes: 1