1

使用 XSLT,我想美化我的 XML 并提取名称空间声明并改用前缀。

我有:

<a xmlns="ns1">
    <b xmlns="ns2">
        <c xmlns="ns3"/>
    </b>
</a>

我想:

<a xmlns="ns1" xmlns:b="ns2" xmlns:c="ns3">
    <b:b>
        <c:c/>
    </b:b>
</a>

自动一步完成此操作将很困难。所以我考虑了多个步骤。每个命名空间一个。

我尝试使用namespace="{namespace-uri(.)}",但无法将命名空间拉到根元素。

4

1 回答 1

4

在您的示例中选择命名空间前缀似乎没有任何明确的逻辑,所以我认为这很难实现,但这里是如何做类似的事情:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exslt="http://exslt.org/common"
                exclude-result-prefixes="exslt">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:key name="kNs" match="*[namespace-uri()]" use="namespace-uri()" />

  <!-- Build a list of elements to represent all namespaces -->
  <xsl:variable name="uniqueNsNf">
    <xsl:for-each select="//*[generate-id() = 
                              generate-id(key('kNs', namespace-uri())[1])]">
      <xsl:element name="ns{position()}:ns" namespace="{namespace-uri()}" />
    </xsl:for-each>
  </xsl:variable>
  <xsl:variable name="uniqueNs" select="exslt:node-set($uniqueNsNf)/*" />

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

  <xsl:template match="*[namespace-uri()]">
    <xsl:variable name="nsMap" 
                  select="$uniqueNs[namespace-uri() = 
                                    namespace-uri(current())]" />
    <xsl:element name="{substring-before(name($nsMap), ':')}:{local-name()}" 
                 namespace="{namespace-uri()}">
      <xsl:copy-of select="$uniqueNs/namespace::*"/>
      <xsl:apply-templates select="@* | node()" />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

在以下输入上运行时:

<a xmlns="ns1">
  <b xmlns="ns2">
    <c xmlns="ns3"/>
    <b xmlns="ns2" />
  </b>

  <d xmlns="otherNs">
    <b xmlns="ns3" />
  </d>
</a>

结果是:

<ns1:a xmlns:ns1="ns1" xmlns:ns2="ns2" xmlns:ns3="ns3" xmlns:ns4="otherNs">
  <ns2:b>
    <ns3:c />
    <ns2:b />
  </ns2:b>

  <ns4:d>
    <ns3:b />
  </ns4:d>
</ns1:a>
于 2013-04-26T10:50:49.593 回答