Группировка списков разделенных узлов XLST - PullRequest
0 голосов
/ 14 сентября 2018

Я использую XSLT 1.0.Есть ли способ разделить набор узлов, используя разделитель, разделить их на группы, а затем получить счетчик группы с большинством узлов?

Мой XML структурирован как:

<Tree>
  <Leaf>
    <Label>Leaf 1</Label>
  </Leaf>
  <Leaf>
    <Label>Leaf 2</Label>
  </Leaf>
  <Leaf>
    <Label>Leaf 3</Label>
  </Leaf>
  <Break />
  <Trunk>
    <Label>Trunk 1</Label>
  </Trunk>
  <Leaf>
    <Label>Leaf 5</Label>
  </Leaf>
  <Stem>
    <Label>Stem 1</Label>
  </Stem>
  <Stem>
    <Label>Stem 2</Label>
  </Stem>
  <Stem>
    <Label>Stem 3</Label>
  </Stem>
  <Break />
  <Trunk>
    <Label>Trunk 2</Label>
  </Trunk>
  <Leaf>
    <Label>Leaf 6</Label>
  </Leaf>
  <Break />
  <Stem>
    <Label>Stem 4 </Label>
  </Stem>
</Tree>

РЕДАКТИРОВАТЬ: Мой разделитель является <Break /> узел.В моем списке может быть много <Break />.Таким образом, исходя из приведенного выше XML, ожидаемые группировки выглядят следующим образом:

1-й набор (Количество = 3): Лист 1, Лист 2 и Лист 3

2-й набор (Количество= 5): ствол 1, лист 5, ствол 1, ствол 2, ствол 3

3-й набор (счет = 2): ствол 2, лист 6

4-й набор (счет = 1): Стебель 4

Ожидаемый результат: "5", потому что это самый высокий счет среди наборов.

1 Ответ

0 голосов
/ 14 сентября 2018

Если вы имеете дело с группировкой в ​​XSLT 1.0, вам нужно использовать технику под названием « Muenchian Grouping »

В вашем случае одним из способов определения группы является подсчет количества предшествующих Break элементов

<xsl:key name="groups" match="Tree/*[not(self::Break)]" use="count(preceding-sibling::Break)" />

Затем, чтобы получить каждую группу, вы делаете это

<xsl:for-each select="*[not(self::Break)][generate-id() = generate-id(key('groups', count(preceding-sibling::Break))[1])]">

Если вы отсортируете это по количеству элементов в группе, первый даст вам максимум.

Попробуйте это XSLT ...

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

  <xsl:key name="groups" match="Tree/*[not(self::Break)]" use="count(preceding-sibling::Break)" />

  <xsl:template match="Tree">
    <xsl:for-each select="*[not(self::Break)][generate-id() = generate-id(key('groups', count(preceding-sibling::Break))[1])]">
      <xsl:sort select="count(key('groups', count(preceding-sibling::Break)))" order="descending" />
      <xsl:if test="position() = 1">
        <xsl:value-of select="count(key('groups', count(preceding-sibling::Break)))" />
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...