質問

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?

役に立ちましたか?

解決

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"/>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top