XSLT将XML中的每个标签计数转换为一些标签

时间:2020-01-31 18:28:56

标签: xml xslt

如何转换具有如下内容的XML:

<info>
   .....
   <name>aaa</name>
</info>
<info>
   .....
   <name>bbb</name>
</info>
<info>
   .....
   <name>ccc</name>
</info>

使用XSLT插入类似这样的内容:

<info>
   .....
   <name1>aaa</name1>
</info>
<info>
   .....
   <name2>bbb</name2>
</info>
<info>
   .....
   <name3>ccc</name3>
</info>

有人知道吗? 谢谢!

2 个答案:

答案 0 :(得分:1)

一种方法是结合使用count(...)preceding-sibling::轴:

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

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

    <!-- Modify all 'name' elements -->
    <xsl:template match="name">
      <xsl:element name="{concat(name(),count(../preceding-sibling::info)+1)}">
        <xsl:apply-templates select="node()|@*" />
      </xsl:element>
    </xsl:template>

</xsl:stylesheet>

输出是所需的。

答案 1 :(得分:1)

我建议使用xsl:number代替同级计数:

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

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

  <xsl:template match="info/name">
      <xsl:variable name="pos">
          <xsl:number count="info"/>
      </xsl:variable>
      <xsl:element name="{name()}{$pos}">
          <xsl:apply-templates/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/ejivJs7

或者在XSLT 3中使用累加器(即使在流传输中也可以使用):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy" use-accumulators="info-count" streamable="yes"/>

  <xsl:accumulator name="info-count" as="xs:integer" initial-value="0" streamable="yes">
      <xsl:accumulator-rule match="info" select="$value + 1"/>
  </xsl:accumulator>

  <xsl:template match="info/name">
      <xsl:element name="{name()}{accumulator-before('info-count')}">
          <xsl:apply-templates/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/ejivJs7/1