I am trying to write a XSLT which will create separate statement segments for each of Statement1/Cliam
, Statement2/Cliam
and Statement3/Cliam
in a sequence. All statement1
, statement2
, statement3
segments we need to replace with Statement segment itself.
My xslt is returning an empty output or mostly the same input. Please have a look at it.
Input sample:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:CustomerMas xmlns:ns0="http://123.com">
<Statement1>
<CustomerAssi_S_IM action="123">
<table>CustomerAss_S_IM</table>
<Cliam>
<Field1>CM</Field1>
</Cliam>
<Cliam>
<Field1>33</Field1>
<Field2>31</Field2>
</Cliam>
</CustomerAssi_S_IM>
</Statement1>
<Statement2>
<CustomerAssi_P_IM action="456">
<table>second</table>
<Cliam>
<Field1>D4</Field1>
</Cliam>
<Cliam>
<Field1>34</Field1>
<Field2>31</Field2>
</Cliam>
</CustomerAssi_P_IM>
</Statement2>
<Statement3>
<CustomerAssi_Q_IM action="789">
<table>second</table>
<Cliam>
<Field1>D4</Field1>
</Cliam>
</CustomerAssi_Q_IM>
</Statement3>
</ns0:CustomerMas>
Output sample:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:CustomerMas xmlns:ns0="http://123.com">
<Statement>
<CustomerAssi_S_IM action="123">
<table>CustomerAss_S_IM</table>
<Cliam>
<Field1>CM</Field1>
</Cliam>
</CustomerAssi_S_IM>
</Statement>
<Statement>
<CustomerAssi_S_IM action="123">
<table>CustomerAss_S_IM</table>
<Cliam>
<Field1>33</Field1>
<Field2>31</Field2>
</Cliam>
</CustomerAssi_S_IM>
</Statement>
<Statement>
<CustomerAssi_P_IM action="456">
<table>second</table>
<Cliam>
<Field1>D4</Field1>
</Cliam>
</CustomerAssi_P_IM>
</Statement>
<Statement>
<CustomerAssi_P_IM action="456">
<table>second</table>
<Cliam>
<Field1>34</Field1>
<Field2>31</Field2>
</Cliam>
</CustomerAssi_P_IM>
</Statement>
<Statement>
<CustomerAssi_Q_IM action="789">
<table>second</table>
<Cliam>
<Field1>D4</Field1>
</Cliam>
</CustomerAssi_Q_IM>
</Statement>
</ns0:CustomerMas>
This is the XSLT I have written so far:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://123.com">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Statement1">
<Statement>
<xsl:for-each select="ns0:CustomerAssi_S_IM/ns0:Cliam">
<Statement>
<CustomerAssi_S_IM>
<xsl:copy-of select="../@*"/>
<xsl:copy-of select="../table"/>
<Cliam>
<xsl:copy-of select="."/>
</Cliam>
</CustomerAssi_S_IM>
</Statement>
</xsl:for-each>
</Statement>
</xsl:template>
<xsl:template match="Statement2">
<Statement>
<xsl:for-each select="ns0:CustomerAssi_P_IM/ns0:Cliam">
<Statement>
<CustomerAssi_P_IM>
<xsl:copy-of select="../@*"/>
<xsl:copy-of select="../table"/>
<Cliam>
<xsl:copy-of select="."/>
</Cliam>
</CustomerAssi_P_IM>
</Statement>
</xsl:for-each>
</Statement>
</xsl:template>
<xsl:template match="Statement3">
<Statement>
<xsl:for-each select="ns0:CustomerAssi_Q_IM/ns0:Cliam">
<Statement>
<CustomerAssi_Q_IM>
<xsl:copy-of select="../@*"/>
<xsl:copy-of select="../table"/>
<Cliam>
<xsl:copy-of select="."/>
</Cliam>
</CustomerAssi_Q_IM>
</Statement>
</xsl:for-each>
</Statement>
</xsl:template>
</xsl:stylesheet>
Your XPaths are not matching your input XML. Only the document element CustomerMas
has the ns0
namespace prefix and is bound to the namespace http://123.com
. The rest of the elements in that document are not bound to any namespace. So, you should not apply ns0
namespace prefix to your XPaths (unless your data actually does match and you posted a bad example XML doc).
You can use a more generic XPath for the for loop and the Claim
parent elements, and construct an element using the name()
of the parent element for that Claim
element.
Inside of the for loop for Claim
the <xsl:copy-of select="."/>
will copy that element, so no need to wrap in another Claim
.
I would consolidate the logic for your template and change the template match to apply to all of the Statement elements:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Statement1|Statement2|Statement3">
<Statement>
<xsl:for-each select="*/Cliam">
<Statement>
<xsl:element name="{name(..)}">
<xsl:copy-of select="../@*"/>
<xsl:copy-of select="../table"/>
<xsl:copy-of select="."/>
</xsl:element>
</Statement>
</xsl:for-each>
</Statement>
</xsl:template>
</xsl:stylesheet>