現在、XSLT 2.0 を使用して大量のデータを処理しようとしています。私の目標は、データ全体で特定のノードが一意に発生するように特定のテンプレートを呼び出すことです。別のロジックに基づいて使用する必要がある他のテンプレートがあるため、「テンプレートの適用」を使用できません。xml は次のような構造になっています。
<root>
<row>
<date>date1</date>
<child>
<ID>001</ID>
</child>
</row>
<row>
<date>date2</date>
<child>
<ID>002</ID>
</child>
</row>
<row>
<date>date1</date>
<child>
<ID>002</ID>
</child>
</row>
<row>
<date>date3</date>
<child>
<ID>002</ID>
</child>
</row>
</root>
理想的には、このシナリオでは 2 つの一意の ID 001 と 002 があるため、その ID に表示される日付の数に関係なく、テンプレートを 2 回呼び出すことになります。キーまたは先行兄弟アプローチのいずれかを使用した例をいくつか見てきました。ただし、構文を正しく理解できないようです。私は次のアプローチを試しました:
呼び出されるテンプレート:
<xsl:template name='doSomething'/>
<xsl:value-of select='child/ID'/>
<xsl:value-of select='date'/>
</template>
====================
<xsl:for-each select='/root/row[not(child/ID = current()child/ID)]
<xsl:call-template name='doSomething'/>
</xsl:for-each>
====================
<xsl:key name='IDs' match='root/row/child/ID' use='.'/>
<xsl:for-each select='root/row[generate-id() = generate-id(key("IDs",.)[1])]>
<xsl:call-template name='doSomething'/>
</xsl:for-each>
====================
<xsl:for-each select='root/row/child/ID[not(. = preceding-sibling::row/child/ID)]>
<xsl:call-template name='doSomething'/>
</xsl:for-each>
XSLT でこれほど洗練されたものを試すのはこれが初めてであり、キーの使用法と軸の構文がどのように機能するかを理解するのにまだ苦労しているため、これが恐ろしいコーディングである場合は申し訳ありません。通常、2.0 では for-each-group を使用します。ただし、ここで for-each-group を試行すると、一意のエントリではなくすべてのエントリが取得されるため、グループ化の仕組みを完全には理解していないと思います。私の最初の試みはこれでした:
<xsl:for-each-group select='root/row' group-by='child/ID'>
<xsl:call-template name='doSomething'/>
</xsl:for-each-group>
====================
私もこれを試しました:
<xsl:for-each-group select='root/row' group-by='child/ID[1]'>
<xsl:call-template name='doSomething'/>
</xsl:for-each-group>
====================
これが完全に正しいわけではないことはわかっていますが、アイデアが尽きて実験していました。これを解決するための指示や支援をいただければ幸いです。あなたが提供できる助けを前もって感謝します。
これが私の望ましい出力です:
001日付1 002日付2
しかし、私は得ています:
001日付1 002日付2 002日付1 002日付3
編集: フィードバックをお寄せいただきありがとうございます。コードのかなり重要な部分を省略していることに気付きました。各 ID には、取引日を表す日付も関連付けられています。また、for-each-group を使用して ID でグループ化できますが、その ID に関連付けられたすべての日付を取得し続け、その ID を含むすべてのエントリではなく、一意の ID のテンプレートのみを呼び出したいと考えています。今起こってる。サンプル出力と電流出力を追加しました。
apply-template の仕組みを誤解している可能性があります。apply-templates を使用すると、xslt 内のすべてのテンプレートが適用されると思いました。特定の条件下で使用されるテンプレートが他に 4 つあります。実際の入力 xml には約 40 の子ノードがあり、ロジックと情報の処理に使用されます。
詳細が必要な場合はお知らせください。
編集:
さらに調査を行った後、キーを使用するのが良い方法のようです。ただし、構文を正しく取得できないようです。これが私の試みです。誰かがそれを修正するのを手伝ってくれますか?
<xsl:key name='IDs' match='child' use='ID'/>
<xsl:template match='/'>
<xsl:for-each select='root/row/child[generate-id(.) = generate-id(key("IDs", ID)[1])]>
<xsl:call-template name='doSomething'/>
</xsl:for-each>
</xsl:template>
明確にしていただきありがとうございます。