0

XML データを 2 つの HTML テーブルにフォーマットしようとしています。いくつかのダミー データ xls:sort を正常に並べ替えることができますが、並べ替えられたデータを別のテーブルに分割することはできません。

私のxml:

<a>
    <b id="N">text1</b>
    <b id="N">text2</b>
    <b id="N+1">text3</b>
    <b id="N">text4</b>
    <b id="N+2">text5</b>
    <b id="N+3">text6</b>
    <b id="N">text7</b>
    <b id="N+2">text8</b>
</a>

この場合、N は数字ですが、どの数字かはわかりません。2 と 55、3 と 4、44 と 52、78 と 98 の可能性があります。

それぞれの番号を独自のテーブルに送信したいので、結果は次のようになります。

<table>
    <tr><td>text1</td></tr>
    <tr><td>text2</td></tr>
    <tr><td>text4</td></tr>
    <tr><td>text7</td></tr>
</table>

<table>
    <tr><td>text3</td></tr>
</table>

<table>
    <tr><td>text5</td></tr>
    <tr><td>text8</td></tr>
</table>

<table>
    <tr><td>text6</td></tr>
</table>

ソートされたデータを属性に応じて異なるテーブルに分割するにはどうすればよいですか?

任意のポインタをいただければ幸いです。

4

1 に答える 1

2

XSLT 1.0 におけるこの種の問題に対する標準的なアプローチは、Muenchian グループ化と呼ばれます。ターゲット要素を好きなようにグループ化するキーを定義します

<xsl:key name="bsById" match="b" use="@id" />

次に、トリックを使用して、各グループの最初のノードのみをグループ全体のプロキシとしてgenerate-id抽出します

<xsl:apply-templates select="b[generate-id()
                             = generate-id(key('bsById', @id)[1])]"
                     mode="group">
  <xsl:sort select="@id" />
</xsl:apply-templates>

したがって、次のテンプレートはグループごとに 1 回起動し、そのkey中で関数を使用してグループ内のすべてのノードを取得できます。

<xsl:template match="b" mode="group">
  <table>
    <!-- extract all the nodes that are grouped with this one -->
    <xsl:apply-templates select="key('bsById', @id)">
      <!-- you could <xsl:sort> here if you want to sort within groups -->
    </xsl:apply-templates>
  </table>
</xsl:template>

<xsl:template match="b">
  <tr><td>...</td></tr>
</xsl:template>

その例が XML 文書全体である場合は上記のすべてで問題ありませんがa、文書内に複数の要素があり、それぞれが個別にグループ化する必要がある独自の要素セットを持ってbいる場合は、キーをより複雑にする必要があります。ここでの通常のトリックはgenerate-id、親aノードの をそのb子のグループ化キー値の一部として使用することです。

<xsl:key name="bsByParentAndId" match="a/b" use="concat(generate-id(..), '|', @id)" />

Muenchian グループ化式の場合

<xsl:template match="a">
  <xsl:apply-templates select="b[generate-id()
                               = generate-id(key('bsByParentAndId', concat(
                                   generate-id(current()), '|', @id))[1])]"
                       mode="group"/>
</xsl:template>

記録として、XSLT 2.0 を使用できれば、非常に簡単になります。複雑なキーを定義する必要はありません。使用するだけですfor-each-group

<xsl:template match="a">
  <xsl:for-each-group select="b" group-by="@id">
    <xsl:sort select="current-grouping-key()" />
    <table>
      <xsl:apply-templates select="current-group()" />
    </table>
  </xsl:for-each-group>
</xsl:template>

<xsl:template match="b">
  <tr><td>...</td></tr>
</xsl:template>
于 2013-08-08T14:34:29.793 に答える