I have this xml:
<pos:getPositionRouter xmlns:pos="positionNS">
<positionID>
<code>1</code>
</positionID>
<parameter>?</parameter>
</pos:getPositionRouter>
and I want to rename the element pos:getPositionRouter to x:getPosition using xslt:
<x:getPosition xmlns:x="newPositionNS">
<positionID>
<code>1</code>
</positionID>
<parameter>?</parameter>
</x:getPosition>
This is the sylesheet I came up with:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:param name="old_namespace" />
<xsl:param name="old_element_localname" />
<xsl:param name="new_namespace" />
<xsl:param name="new_element_localname" />
<xsl:template match="@*|node()">
<xsl:choose>
<xsl:when test="(local-name() = $old_element_localname) and (namespace-uri() = $old_namespace)">
<xsl:element name="{$new_element_localname}" namespace="{$new_namespace}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<!-- copy the rest as is -->
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
I am forced to use xalan as xslt processor, and the output, unfortunately is this:
<getPosition xmlns="newPositionNS">
<positionID xmlns:pos="positionNS">
<code>1</code>
</positionID>
<parameter xmlns:pos="positionNS">?</parameter>
</getPosition>
The default namespace of the getPosition element becomes the new namespace, but the child elements should remain without namespace (xmlns="").
Can someone understand why?
Thank you!
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="old_namespace" select="'positionNS'"/>
<xsl:param name="old_element_localname" select="'getPositionRouter'"/>
<xsl:param name="new_namespace_prefix" select="'x'"/>
<xsl:param name="new_namespace" select="'newPositionNS'"/>
<xsl:param name="new_element_localname" select="'getPosition'" />
<xsl:template match="*">
<xsl:choose>
<xsl:when test="local-name()=$old_element_localname and
namespace-uri()=$old_namespace">
<xsl:element
name="{substring(concat($new_namespace_prefix,':'),
1 div boolean($new_namespace_prefix))}{
$new_element_localname}"
namespace="{$new_namespace}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Output:
<x:getPosition xmlns:x="newPositionNS">
<positionID>
<code>1</code>
</positionID>
<parameter>?</parameter>
</x:getPosition>
Note: If you want an specific prefix you should add it to the QName. If you want to remove in-scope namespace you shouldn't use xsl:copy in XSLT 1.0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With