XSLT の複雑さについて詳しく知りたい場合は、問題を解決するために使用できるMuenchian Groupingと呼ばれる手法について知りたいと思うかもしれません。個別の行を取得するには、attribute1で効果的にグループ化し、グループごとにグループ内の最初の要素を選択します。(または最初ではない要素を破棄します)。Muenchian Grouping は、XSLT 1.0 でこれを実現する最も効率的な方法です。
この場合、グループを示すキーを定義することから始めます。この場合は、attribute1でグループ化された行要素です。
<xsl:key name="row" match="row" use="@attribute1" />
次に、個別の行要素を選択する場合は、指定された属性のキーで最初に出現した行要素を選択します1
<xsl:apply-templates select="row[generate-id() = generate-id(key('row', @attribute1)[1])]" />
または、重複する行要素 (つまり、グループの最初ではない要素)を無視するテンプレートを使用することもできます。
<xsl:template match="row[generate-id() != generate-id(key('row', @attribute1)[1])]" />
このXSLTを試してください
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="row" match="row" use="@attribute1" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="row[generate-id() != generate-id(key('row', @attribute1)[1])]" />
</xsl:stylesheet>
以下のXMLに当てはめると
<rows>
<row attribute1="1" attribute2="something" attribute3="somevalue" />
<row attribute1="1" attribute2="something" attribute3="somevalue" />
<row attribute1="2" attribute2="anotherthing" attribute3="somevalue" />
</rows>
以下が出力されます
<rows>
<row attribute1="1" attribute2="something" attribute3="somevalue"></row>
<row attribute1="2" attribute2="anotherthing" attribute3="somevalue"></row>
</rows>
ljdelight の回答で説明されているように、XSLT を簡単に拡張して、属性の名前を変更したり、属性を除外したりできます。さらに、テストに 2 番目の属性を含めたい場合は、次のようにキーを拡張できます。
<xsl:key name="row" match="row" use="concat(@attribute1, '|', @attribute3)" />
重複を無視するために、テンプレートは次のようになります。
<xsl:template match="row
[generate-id() != generate-id(key('row', concat(@attribute1, '|', @attribute3))[1])]" />
ここで注意すべき唯一のことは、パイプ文字 | の使用です。区切り文字として。これは、属性値に出現しない限り、必要に応じて他の文字にすることができます。