18

我有一些 XML 声明了一个仅用于属性的命名空间,如下所示:

<?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>。我尝试在 XSL 中声明命名空间并将前缀放在exclude-result-prefixes列表中,但这似乎没有任何效果。我究竟做错了什么?

更新:我发现通过在 XSL 中声明命名空间并使用extension-element-prefixes属性有效,但这似乎不对!我想我可以使用它,但我想知道为什么exclude-result-prefixes它不起作用!

更新:实际上,这个extension-element-prefixes解决方案似乎只适用于 XMLSpy 的内置 XSLT 引擎,而不适用于 MSXML。

4

4 回答 4

9
<?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>

我在这里找到了解释。

Michael Kay 写道:
exclude-result-prefixes 只影响通过文字结果元素从样式表复制的名称空间,它不影响从源文档复制名称空间。

于 2009-07-02T16:17:12.897 回答
5
<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>
于 2009-07-03T09:52:49.873 回答
4

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

<xsl:template match="node()">
    <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>
于 2012-03-28T15:16:27.750 回答
2

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

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

处理默认命名空间时,请记住做两件事。首先将其映射到样式表标记中的某些内容,然后使用命名空间别名将其删除。

于 2011-11-30T09:26:42.247 回答