xslt-替换属性中的命名空间

时间:2013-10-24 09:06:45

标签: xml xslt-1.0

我有以下xml,想在输入xml中用“http://tester.com”替换名称空间“http://tester.com/v2”。我已经提到了Dimitre的解决方案here,能够提出一个xslt(1.0)。它正在替换所有元素的命名空间,但属性不是。我如何修改它,以便更换甚至适用于属性?

输入xml

<a:Root xmlns:a="http://tester.com">
    <a:we>er</a:we>
    <a:ty a:yu="samp">gh</a:ty>
</a:Root>

期望的输出

<a:Root xmlns:a="http://tester.com/v2">
    <a:we>er</a:we>
    <a:ty a:yu="samp">gh</a:ty>
</a:Root>

xslt尝试了

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pTarget" select="'http://tester.com'"/>
 <xsl:param name="pRepl" select="'http://tester.com/v2'"/>

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

 <xsl:template match=
  "*[namespace-uri()='http://tester.com'
   or
     namespace::*[.='http://tester.com']
    ]">

  <xsl:variable name="vNS" select="namespace-uri()"/>

  <xsl:variable name="vNewNS">
    <xsl:choose>
      <xsl:when test="not($vNS=$pTarget)">
        <xsl:value-of select="$vNS"/>
      </xsl:when>
      <xsl:otherwise>

        <xsl:value-of select="$pRepl"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:element name="{name()}" namespace="{$vNewNS}">
   <xsl:copy-of select=
     "namespace::*
        [not(. = $vNS
            or
             .='http://tester.com'
             )
        ]"/>

   <xsl:for-each select=
     "namespace::*
        [.='http://tester.com'
        ]">
     <xsl:variable name="vNewNSUri" select=
     "$pRepl
     "/>

     <xsl:variable name="vPrefix" select="name()"/>

     <xsl:variable name="vPref">
       <xsl:if test="$vPrefix">
         <xsl:value-of select="concat($vPrefix, ':')"/>
       </xsl:if>
     </xsl:variable>

     <xsl:variable name="vrtfDoc">
      <xsl:element name="{$vPref}dummy"
                   namespace="{$vNewNSUri}"/>
     </xsl:variable>

     <xsl:copy-of select=
     "ext:node-set($vrtfDoc)/*/namespace::*[. = $vNewNSUri]"/>
   </xsl:for-each>

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

1 个答案:

答案 0 :(得分:0)

你想要这样的东西:

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

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

加上不在此命名空间中的元素/属性的标识模板。