代码之家  ›  专栏  ›  技术社区  ›  Graham Clark

XSL-复制元素但删除未使用的命名空间

  •  18
  • Graham Clark  · 技术社区  · 16 年前

    <?xml version="1.0" encoding="UTF-8"?>
    <a xmlns:x="http://tempuri.com">
        <b>
            <c x:att="true"/>
            <d>hello</d>
        </b>
    </a>
    

    我想使用XSL创建所选节点及其值的副本—去掉属性。因此,我期望的输出是:

    <?xml version="1.0" encoding="UTF-8"?>
    <b>
        <c />
        <d>hello</d>
    </b>
    

    我有一些XSL几乎可以做到这一点,但我似乎无法阻止它将名称空间声明放在输出的顶级元素中。我的XSL是:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/">
            <xsl:apply-templates select="/a/b"/>
        </xsl:template>
    
        <xsl:template match="node()">
            <xsl:copy>
                <xsl:apply-templates select="node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    输出的第一个元素是 <b xmlns:x="http://tempuri.com"> 而不是 <b> exclude-result-prefixes 列表,但这似乎没有任何效果。我做错了什么?

    extension-element-prefixes 属性有效,但这似乎不正确!我想我可以用这个,但我想知道为什么 排除结果前缀 不行!

    更新:事实上,看起来是这样的 扩展元素前缀

    4 回复  |  直到 16 年前
        1
  •  9
  •   steamer25    16 年前
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
        xmlns:x="http://tempuri.com">
        <xsl:template match="/">
            <xsl:apply-templates select="/a/b"/>
        </xsl:template>
    
        <xsl:template match="*">
            <xsl:element name="{local-name(.)}">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
    
        <xsl:template match="@*">
            <xsl:copy/>
        </xsl:template>
    
        <!-- This empty template is not needed.
    Neither is the xmlns declaration above:
        <xsl:template match="@x:*"/> -->
    </xsl:stylesheet>
    

    我找到了一个解释 here .

    迈克尔·凯写道:
    排除结果前缀仅影响从中复制的命名空间 由文本结果元素创建的样式表,它不影响 源文档中的名称空间。

        2
  •  5
  •   Tomalak    16 年前
    <xsl:stylesheet 
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:x="http://tempuri.com"
      exclude-result-prefixes="x"
    >
    
      <!-- the identity template copies everything 1:1 -->
      <xsl:template match="@* | node()">
         <xsl:copy>
          <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
      </xsl:template>
    
      <!-- this template explicitly cares for namespace'd attributes -->
      <xsl:template match="@x:*">
        <xsl:attribute name="{local-name()}">
          <xsl:value-of select="." />
        </xsl:attribute>
      </xsl:template>
    
    </xsl:stylesheet>
    
        3
  •  4
  •   legoscia    13 年前

    试试这个(注意属性) copy-namespaces='no'

    <xsl:template match="node()">
        <xsl:copy copy-namespaces="no">
                <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    
        4
  •  2
  •   Stephan    13 年前

    这将从输出中删除x命名空间。

    <xsl:namespace-alias result-prefix="#default" stylesheet-prefix="x" />