如何在XSLT中循环并生成匹配节点的计数?

时间:2019-01-04 16:45:37

标签: xml xslt xpath

我需要遍历XML数据并生成一个文档,该文档将说明文本在节点中出现了多少次。我已经接近了,但无法正常工作。我正在使用xsl 1.0,无法更新它。

<xsl:variable name="found">
 <root>
    <content name="test">A</content>
    <content name="test">A</content>
    <content name="test">A</content>
    <content name="test">B</content>
    <content name="test">B</content>
    <content name="test">C</content>
  </root>
</xsl:variable>


<xsl:template match="document">
  <document>
    <xsl:for-each select="exsl:node-set($found)//content[@name='test']">
      <content name="found-count">
        <xsl:value-of select="." />,<xsl:value-of
          select="count(exsl:node-set($found)//content[.= text()])"
        />
      </content>
    </xsl:for-each>
  </document>
</xsl:template>

输出为...

<document>
  <content name="found-count">A,6</content>
  <content name="found-count">A,6</content>
  <content name="found-count">A,6</content>
  <content name="found-count">B,6</content>
  <content name="found-count">B,6</content>
  <content name="found-count">C,6</content>
</document>

我需要它(我将在以后删除重复数据):

<document>
  <content name="found-count">A,3</content>
  <content name="found-count">A,3</content>
  <content name="found-count">A,3</content>
  <content name="found-count">B,2</content>
  <content name="found-count">B,2</content>
  <content name="found-count">C,1</content>
</document>

我认为问题出在我的陈述中

<xsl:value-of select="count(exsl:node-set($found)//content[.= text()])" />

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

替换此...

<xsl:value-of select="count(exsl:node-set($found)//content[.= text()])"

有了这个...

<xsl:value-of select="count(exsl:node-set($found)//content[.= current()/text()])"

current()节点是父级content选择的xsl:for-each。如果不指定current(),则执行content[.= text()])与执行content[.= ./text()])相同(即,它指向上下文节点),因此您将获得文本与其自身相等的内容。

或者,在此处使用xsl:key,然后执行此操作。...

<xsl:key name="content" match="content[@name='test']" use="." />

<xsl:template match="document">
  <document>
    <xsl:for-each select="exsl:node-set($found)">
      <xsl:for-each select=".//content[@name='test']">
        <content name="found-count">
          <xsl:value-of select="." />,<xsl:value-of select="count(key('content', text()))" />
        </content>
      </xsl:for-each>
    </xsl:for-each>
  </document>
</xsl:template>

这样,您就可以使用Muenchian Grouping进行重复数据删除了...

<xsl:template match="document">
  <document>
    <xsl:for-each select="exsl:node-set($found)">
      <xsl:for-each select=".//content[@name='test'][generate-id() = generate-id(key('content', text())[1])]">
        <content name="found-count">
          <xsl:value-of select="." />,<xsl:value-of select="count(key('content', text()))" />
        </content>
      </xsl:for-each>
    </xsl:for-each>
  </document>
</xsl:template>