Reputation: 2097
This is my input XML
<?xml version="1.0"?>
<myroot xmlns="http://www.myroot.com/v0.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<A>TestProject1</A>
<B>ValueB</B>
</myroot>
I want to change the default namespace to 0.2 and add some new attributes throught XSLT tranformation. I am able to to that but in my output xml old namespace aliases are not retained like xmlns:xsd and xmlns:xsi.
Any anybody point out what is wrong with my xslt.
Here is my XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:previous="http://www.myroot.com/v0.1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
<!-- Copy the current node -->
<xsl:copy >
<!-- Including any attributes it has and any child nodes -->
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="previous:myroot">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
<xsl:element name="NewElement">1234</xsl:element>
</xsl:copy>
</xsl:template>
<xsl:template
match="//*[namespace-uri()='http://www.myroot.com/v0.1']">
<xsl:element name="{local-name()}"
namespace="http://www.myroot.com/v0.2">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
and this is output xml(with missing xsi and xsd namespaces)
<?xml version="1.0"?>
<myroot xmlns="http://www.myroot.com/v0.2" >
<A>TestProject1</A>
<B>ValueB</B>
<NewElement>1234</NewElement>
</myroot>
but * Expected Output is
<?xml version="1.0"?>
<myroot xmlns="http://www.myroot.com/v0.1"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<A>TestProject1</A>
<B>ValueB</B>
<NewElement>1234</NewElement>
</myroot>
Upvotes: 0
Views: 120
Reputation: 1695
One solution can be: (optimizing a bit)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:previous="http://www.myroot.com/v0.1"
xmlns:new="http://www.myroot.com/v0.2"
version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="previous:*">
<xsl:element name="{local-name()}" namespace="http://www.myroot.com/v0.2">
<xsl:copy-of select="@* | namespace::*[not(. = 'http://www.myroot.com/v0.1')]"/>
<xsl:choose>
<xsl:when test="local-name() = 'myroot'">
<xsl:element name="NewElement">1234</xsl:element>
<xsl:apply-templates/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bFN1y8X/6
Upvotes: 2
Reputation: 167401
I would suggest to copy namespace nodes explicitly:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:previous="http://www.myroot.com/v0.1"
version="1.0">
<xsl:template match="previous:*">
<xsl:element name="{local-name()}" namespace="http://www.myroot.com/v0.2">
<xsl:copy-of select="@* | namespace::*[not(. = 'http://www.myroot.com/v0.1')]"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bFN1y8X
If you want to add a new element inside a certain element like the root element then add an additional template for that. It is also possible to move the new namespace to the stylesheet's root element if you need to use it for all result elements:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:previous="http://www.myroot.com/v0.1"
exclude-result-prefixes="previous"
xmlns="http://www.myroot.com/v0.2"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="previous:*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@* | namespace::*[not(. = 'http://www.myroot.com/v0.1')]"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="/previous:*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@* | namespace::*[not(. = 'http://www.myroot.com/v0.1')]"/>
<xsl:apply-templates/>
<NewElement>1234</NewElement>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bFN1y8X/4
Upvotes: 2