0

私は次のアイテムのリストを持っています。

<items>
    <item type="Type1">Item1</item>
    <item type="Type2">Item2<item>
    <item type="Type2">Item3<item>
    <item type="Type3">Item4<item>
    <item type="Type3">Item5<item>
    <item type="Type1">Item6<item>
    <item type="Type3">Item7<item>
    <item type="Type1">Item8<item>
    <item type="Type2">Item9<item>
    <item type="Type1">Item10<item>
<items>

上記が Type1(x1)、Type2(x2)、Type3(x4) のグループで表示されるように、必要な XSLT を理解するのに問題があります。ここで、カウントは括弧内の数字以下です。言い換えると、目標は繰り返しパターンを作成することです: Type1 の次のアイテムが残っている場合は、次に Type2 の次の 2 つ以下のアイテムが残っている場合は 2 つ未満であり、次に Type3 の次の 4 つ以下のアイテムが少ない場合はそれ以下です。 4つ以上残っています。

したがって、目的の出力は次のようになります。

<div class="Items">
    <div class="Type1">Item1</div>
    <div class="Type2">Item2</div>
    <div class="Type2">Item3</div>
    <div class="Type3">Item4</div>
    <div class="Type3">Item5</div>
    <div class="Type3">Item7</div>
    <div class="Type1">Item6</div>
    <div class="Type2">Item9</div>
    <div class="Type1">Item8</div>
    <div class="Type1">Item10</div>
</div>

上記の出力から、順序が変更されていることがわかります。つまり、<=1 の Type 1 があり、その後に <=2 の Type2 が続き、その後に <=4 の Type3 が続き、このパターンが繰り返されます。項目を説明したパターンにグループ化し、項目が使い果たされた場合は完全なリストになるまで繰り返す必要があると思います。私が理にかなっていることを願っています。

誰でも必要な XSLT またはいくつかのポインターを提供できますか?

ありがとう、ジョン。

4

1 に答える 1

0

これを試してください:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:key name="kType2Group" match="item[@type = 'Type2']"
           use="floor(count(preceding-sibling::item[@type = 'Type2']) div 2) + 1"/>
  <xsl:key name="kType3Group" match="item[@type = 'Type3']"
           use="floor(count(preceding-sibling::item[@type = 'Type3']) div 4) + 1"/>

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

  <xsl:template match="/*">
    <xsl:copy>
      <xsl:apply-templates select="item[@type = 'Type1']" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="item[@type = 'Type1']">
    <xsl:call-template name="Copy" />
    <xsl:apply-templates select="key('kType2Group', position())" />
    <xsl:apply-templates select="key('kType3Group', position())" />
  </xsl:template>
</xsl:stylesheet>

入力 XML で実行すると、結果は次のようになります。

<items>
  <item type="Type1">Item1</item>
  <item type="Type2">Item2</item>
  <item type="Type2">Item3</item>
  <item type="Type3">Item4</item>
  <item type="Type3">Item5</item>
  <item type="Type3">Item7</item>
  <item type="Type1">Item6</item>
  <item type="Type2">Item9</item>
  <item type="Type1">Item8</item>
  <item type="Type1">Item10</item>
</items>

この場合のキーは、Type2 アイテムと Type3 アイテムをグループに分けるために使用され、グループ番号 (1、2、3 など) で取得できるようにします。グループ番号を決定するロジックは、その数を各グループのアイテム数で割り、切り捨てて 1 を足します。たとえば、最初の 4 つの Type2 に対して実行されるこの計算は次のようになります。

floor(0 div 2) + 1 = floor(0) + 1 = 0 + 1 = 1
floor(1 div 2) + 1 = floor(0.5) + 1 = 0 + 1 = 1
floor(2 div 2) + 1 = floor(1) + 1 = 1 + 1 = 2
floor(3 div 2) + 1 = floor(1.5) + 1 = 1 + 1 = 2

等々。

XSLT の一般的なロジックは次のとおりです。

  • ルート要素を一致させてコピーし、すべての Type1 アイテムにテンプレートを適用します。
  • Type1 アイテムのテンプレート:
    • アイテム自体をコピーします。
    • キーを使用して、そのグループ内の Type2 項目にテンプレートを適用します (position()最初の Type1 項目では 1、2 番目の Type1 項目では 2 というようになります。
    • キーを使用して、そのグループ内の Type3 アイテムにテンプレートを適用します
  • 最初のテンプレートである ID テンプレートは、一致するテンプレートが他にないものをすべてコピーする役割を果たします。
于 2013-05-16T06:11:00.250 に答える