I. この XPath 2.0 ワンライナーを使用します。
/*/choice/*[name() = /*/choices/*/name()][1]
この XPath 式が次の XML ドキュメント(提供されたものですが、整形式の XML ドキュメントになるように修正されています) に対して評価される場合:
<t>
<choices>
<sic />
<corr />
<reg />
<orig />
</choices>
<choice>
<corr>Red</corr>
<sic>Blue</sic>
</choice>
</t>
正しい要素が選択されています:
<corr>Red</corr>
Ⅱ.XSLT 1.0 (キーなし!):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vNames">
<xsl:for-each select="/*/choices/*">
<xsl:value-of select="concat(' ', name(), ' ')"/>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<xsl:copy-of select=
"/*/choice/*
[contains($vNames, concat(' ', name(), ' '))]
[1]"/>
</xsl:template>
</xsl:stylesheet>
この変換が同じ XML ドキュメント (上記) に適用されると、再び正しい要素が選択されます (出力にコピーされます)。
<corr>Red</corr>
III. キーの使用:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kChoiceByName" match="choice/*"
use="boolean(/*/choices/*[name()=name(current())])"/>
<xsl:template match="/">
<xsl:copy-of select="/*/choice/*[key('kChoiceByName', true())][1]"/>
</xsl:template>
</xsl:stylesheet>
この変換が同じ XML ドキュメント (上記) に対して適用されると、同じ正しい結果が生成されます。
<corr>Red</corr>
これがどのように「機能する」かを理解しようとすることを読者にお勧めします:)