Как я могу зациклить и сгенерировать количество совпадающих узлов в XSLT? - PullRequest
0 голосов
/ 04 января 2019

Мне нужно перебрать данные 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 голосов
/ 04 января 2019

Заменить это ...

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...