Question

I have an xml which I'd like to change the namespace of most elements, remove some specific element names and also remove elements which contains a specific namespace. Example of such an xml

<root xmlns="somenamespace">
   <elem1>sometext</eleme1>
   <ns0:elem2 xmlns:ns0="othernamespace">
       <ns1:elem3 xmlns:ns1="thirdnamespace" />
   </ns0:elem2>
   <elem4>sometext</elem4>
</root>

I am trying to use the following xslt:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    
    <xsl:template match="*[namespace-uri() = 'somenamespace']">
        <xsl:choose>
            <!-- change element name from root to root2 -->
            <xsl:when test="local-name(.)='root'">
                <xsl:element name="root2" namespace="mynamespace">
                    <xsl:apply-templates select="@* | node()" />
                </xsl:element>
            </xsl:when>
            <!-- skip these elements that are not in root2 -->
            <xsl:when test="local-name(.)='elem1'" />
            <xsl:when test="namespace-uri()='othernamespace'" />
            <!-- Copy other elemnts -->
            <xsl:otherwise>
                <xsl:element name="{name()}" namespace="mynamespace">
                    <xsl:apply-templates select="@* | node()" />
                </xsl:element>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <!-- Copy the rest -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

The output xml should be

<root2 xmlns="mynamespace">
   <elem4>sometext</elem4>
</root2>

However the result is

<root2 xmlns="mynamespace" xmlns:ns0="othernamespace">
   <ns0:elem2>
       <ns1:elem3 xmlns:ns1="thirdnamespace" />
   </ns0:elem2>
   <elem4>sometext</elem4>
</root2>

It seems that most elements of the xslt are working except the one that is supposed to remove all elements of a specific namespace. Is there anything wrong in the xslt above?

Était-ce utile?

La solution

Your first template is only matching elements in the somenamespace namespace. The other namespaces (othernamespace,thirdnamespace) are matched by the identity transform (last template) and are output as-is.

To strip all elements that aren't in the somenamespace namespace, add this template:

<xsl:template match="*[not(namespace-uri()='somenamespace')]" priority="1"/>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top