この解決策は、リチャードが提示したものよりも少し単純で効率的であると同時に、より一般的です。
この変換:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- -->
<xsl:key name="kFileByVal" match="File"
use="." />
<!-- -->
<xsl:key name="kDescByFile" match="Description"
use="../File"/>
<!-- -->
<xsl:template match="/*">
<html>
<body>
<xsl:for-each select=
"*/File[generate-id()
=
generate-id(key('kFileByVal',.)[1])]">
<h1><xsl:value-of select="."/></h1>
<xsl:for-each select="key('kDescByFile', .)">
<p><xsl:value-of select="."/></p>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
提供された XML ドキュメントに適用された場合:
<Problems>
<Problem>
<File>file1</File>
<Description>desc1</Description>
</Problem>
<Problem>
<File>file1</File>
<Description>desc2</Description>
</Problem>
<Problem>
<File>file2</File>
<Description>desc1</Description>
</Problem>
</Problems>
必要な結果を生成します:
<html>
<body>
<h1>file1</h1>
<p>desc1</p>
<p>desc2</p>
<h1>file2</h1>
<p>desc1</p>
</body>
</html>
最初の単純一致パターンと<xsl:key>
、2 番目の を使用して、指定された値を持つ要素の兄弟である<xsl:key>
すべての " " 要素を見つける方法に注意してください。Description
File
プル処理の代わりにより多くのテンプレートを使用することもできましたが<xsl:for-each>
、これは非常に単純なケースであり、ソリューションはより短く、よりコンパクトで読みやすいコードから本当に恩恵を受けます。
また、XSLT 2.0 では通常、 <xsl:for-each-group>
Muenchian メソッドの代わりに命令を使用することに注意してください。