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>
三、使用键:
<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>
建议读者尝试了解这一切是如何“工作”的:)