Removing a tag with XLST: namespace issue

喜你入骨 提交于 2021-01-28 09:15:17

问题


I'm new to XSLT.

I'm trying to create a simple transformation which would remove a certain tag from an XML file. The tag I'm trying to remove has a namespace declaration. The idea is to get out of the following input:

<?xml version="1.0" encoding="utf-8" ?> 
<ToBeRemoved xlmns:prx="urn:something">
<n0:ToRemain xlmns:n0="https://somethingelse.com/def.xsd">
<Data>
...
</Data>
</n0:ToRemain>
</ToBeRemoved>

the following:

<?xml version="1.0" encoding="utf-8" ?> 
<n0:ToRemain xlmns:n0="https://somethingelse.com/def.xsd">
<Data>
...
</Data>
</n0:ToRemain>

I'm using the following XSLT:

<xsl:transform version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

<xsl:strip-space elements="*"/>

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

<xsl:template match="ToBeRemoved">
   <xsl:apply-templates select="node()|@*" />
</xsl:template>

</xsl:transform>

Unfortunately, the namespace declaration from doesn't get completely deleted, but "sticks" somehow to the next tag :

<?xml version="1.0" encoding="utf-8" ?> 
<n0:ToRemain xlmns:n0="https://somethingelse.com/def.xsd"   
xlmns:prx="urn:something">
<Data>
...
</Data>
</n0:ToRemain>

Any ideas?

Thanks!!!


回答1:


In XSLT 1.0, which you appear to be using, the xsl:copy instruction also copies all namespaces that are in scope for the copied node.

To prevent this, create a new element instead of copying the existing one - i.e. replace the identity transform template:

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

with:

<xsl:template match="*">
    <xsl:element name="{name()}" namespace="{namespace-uri()}">
        <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
</xsl:template>

and optionally (if you also have attributes and/or comments and /or processing instructions that you want to preserve):

<xsl:template match="@*">
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
        <xsl:value-of select="." />
    </xsl:attribute>
</xsl:template>

<xsl:template match="comment() | processing-instruction()">
    <xsl:copy/>
</xsl:template>


来源:https://stackoverflow.com/questions/45214297/removing-a-tag-with-xlst-namespace-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!