如何在XSLT中限定Key查找的上下文范围?
问题
有一个包含多个<home>父节点的XML,需要在每个<home>节点内查找指定节点。由于Key的输入值(示例中为'4')是从其他节点动态获取的,必须使用Key。请问如何将Key查找的上下文限定在调用它的当前<home>节点范围内?
输入XML
<homes> <home> <to-reno>one</to-reno> <bedrooms name="master1">1</bedrooms> <bedrooms name="master2">2</bedrooms> <bedrooms name="master3">3</bedrooms> </home> <home> <to-reno>two</to-reno> <bedrooms name="master4">4</bedrooms> <bedrooms name="master5">5</bedrooms> </home> </homes>
当前XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:key name="data-set" match="bedrooms" use="."/> <xsl:template match="*|@*"> <xsl:copy> <xsl:apply-templates select="*|@*"/> </xsl:copy> </xsl:template> <xsl:template match="home"> <xsl:variable name="keyNode" select="key('data-set', '4')"/> <xsl:if test="$keyNode"> <to-reno> <type> <xsl:value-of select="to-reno"/> </type> <name> <xsl:value-of select="$keyNode/@name"/> </name> </to-reno> </xsl:if> </xsl:template> </xsl:stylesheet>
当前输出
<homes> <to-reno> <type>one</type> <name>master4</name> </to-reno> <to-reno> <type>two</type> <name>master4</name> </to-reno> </homes>
期望输出
<homes> <to-reno> <type>two</type> <name>master4</name> </to-reno> </homes>
解决方案
XSLT 2.0及以上版本的key()函数支持第三个可选参数,用来限定查找的上下文节点集。只需要在调用key()时,将当前的<home>节点作为第三个参数传入,就能把查找范围限制在当前<home>内部。
修改后的关键代码是将:
<xsl:variable name="keyNode" select="key('data-set', '4')"/>
替换为:
<xsl:variable name="keyNode" select="key('data-set', '4', .)"/>
修改后的完整XSLT代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:key name="data-set" match="bedrooms" use="."/> <xsl:template match="*|@*"> <xsl:copy> <xsl:apply-templates select="*|@*"/> </xsl:copy> </xsl:template> <xsl:template match="home"> <xsl:variable name="keyNode" select="key('data-set', '4', .)"/> <xsl:if test="$keyNode"> <to-reno> <type> <xsl:value-of select="to-reno"/> </type> <name> <xsl:value-of select="$keyNode/@name"/> </name> </to-reno> </xsl:if> </xsl:template> </xsl:stylesheet>
这样修改后,每个<home>节点只会在自身范围内查找匹配key值为'4'的<bedrooms>节点,只有第二个<home>节点符合条件,最终输出与期望结果一致。
内容的提问来源于stack exchange,提问作者asb
相关产品推荐
相关产品推荐

