I am trying to convert attributes into elements, along with this, I want to change namespace prefix of my XML code. XML code:
<lm:GetInvoiceList xmlns:lm="http://www.w3.org">
<lm:Response>
<lm:Bill>
<lm:BillStatusCode typecode="1">type description</lm:BillStatusCode>
<lm:EBillProcessStatusCode typecode="2">type description</lm:EBillProcessStatusCode>
<lm:BillCycleCode typecode="1">type description</lm:BillCycleCode>
<lm:BillActivityCode typecode="3">type description</lm:BillActivityCode>
<lm:ToDate>...</lm:ToDate>
</lm:Bill>
</lm:Response>
</lm:GetInvoiceList>
I have this XSLT code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@*]">
<xsl:copy>
<xsl:element name="ns:{name()}">
<xsl:apply-templates select="node()"/>
</xsl:element>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*|*[@*]">
<xsl:element name="ns:{local-name()}" namespace="http://my.ns.uri">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="ns:{name()}" namespace="http://my.ns.uri">
<xsl:copy-of select="namespace::*"/>
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
But I am not getting the desired output.
Expected Output:
<ns:GetInvoiceList xmlns:ns="http://my.ns.uri">
<ns:Response>
<ns:Bill>
<ns:BillStatusCode>
<ns:BillStatusCode>type description</ns:BillStatusCode>
<ns:typecode>1</ns:typecode>
</ns:BillStatusCode>
<ns:EBillProcessStatusCode>
<ns:EBillProcessStatusCode>type description</ns:EBillProcessStatusCode>
<ns:typecode>2</ns:typecode>
</ns:EBillProcessStatusCode>
<ns:BillCycleCode>
<ns:BillCycleCode>type description</ns:BillCycleCode>
<ns:typecode>1</ns:typecode>
</ns:BillCycleCode>
<ns:BillActivityCode>
<ns:BillActivityCode>type description</ns:BillActivityCode>
<ns:typecode>3</ns:typecode>
</ns:BillActivityCode>
<ns:ToDate>...</ns:ToDate>
</ns:Bill>
</ns:Response>
</ns:GetInvoiceList>
Actual output:
<ns:GetInvoiceList xmlns:ns="http://my.ns.uri">
<ns:Response>
<ns:Bill>
<ns:BillStatusCode>
<ns:typecode>1</ns:typecode>type description</ns:BillStatusCode>
<ns:EBillProcessStatusCode>
<ns:typecode>2</ns:typecode>type description</ns:EBillProcessStatusCode>
<ns:BillCycleCode>
<ns:typecode>1</ns:typecode>type description</ns:BillCycleCode>
<ns:BillActivityCode>
<ns:typecode>3</ns:typecode>type description</ns:BillActivityCode>
<ns:ToDate>...</ns:ToDate>
</ns:Bill>
</ns:Response>
</ns:GetInvoiceList>
Would Appreciate any help on this!
In view of your clarifications in the comments, I would suggest:
XSLT 1.0
What's the difference?
When applied to the following example input:
XML
the result will be:
as opposed to:
which places the "second property" text node incorrectly under another instance of
ns:BillPropertyA
and makes that a child ofns:BillPropertyC
.Notes:
If you want to change the namespace of a node, you cannot use
xsl:copy
, since that would also copy the existing namespace;You can (and should) declare the namespace once, then use the already existing binding where necessary.
Try this XSLT:
Output: