I. これは、単一の XPath 式を使用して見つけることができます。
false()
or
/*/*/*/RNumber
[@Type='VolumeNumber'
and
. = ../preceding-sibling::*
/RNumber[@Type='VolumeNumber']
]
この XPath 式を評価し、この評価の結果を出力する完全な XSLT 変換を次に示します。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
Duplicate volume numbers exist: <xsl:text/>
<xsl:value-of select=
"false()
or
/*/*/*/RNumber
[@Type='VolumeNumber'
and
. = ../preceding-sibling::*
/RNumber[@Type='VolumeNumber']
]
"/>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用されると、次のようになります。
<BookList>
<Book>
<History>
<Type>history</Type>
<Prize>123</Prize>
<Publication>``
<Name>YEAP1</Name>
</Publication>
<RNumber Type="VolumeNumber">11111</RNumber>
<RNumber Type="SupplementNumber">123456</RNumber>
</History>
<chemistry>
<Type>chemistry</Type>
<Prize>333</Prize>
<Publication>
<Name>YEAP</Name>
</Publication>
<RNumber Type="VolumeNumber">11111</RNumber>
<RNumber Type="SupplementNumber">45454</RNumber>
</chemistry>
......
</Book>
</BookList>
必要な正しい結果が生成されます。
Duplicate volume numbers exist: true
Ⅱ.キーを使用したソリューション (一般的により効率的):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kVolNum" match="RNumber[@Type='VolumeNumber']"
use="."/>
<xsl:template match="/">
Duplicate volume numbers exist: <xsl:text/>
<xsl:value-of select=
"false()
or
/*/*/*/RNumber
[@Type='VolumeNumber'
and
key('kVolNum',.)[2]
]"/>
</xsl:template>
</xsl:stylesheet>
この変換を同じ XML ドキュメント (上記) に適用すると、同じ正しい結果が生成されます。
Duplicate volume numbers exist: true