在模板名称P中,我想检查当前节点的名称是否为Fox。我想知道人们做这种检查的通常方式是什么:
<xsl:template name="P">
<xsl:if test="self::Fox">
</xsl:if>
</xsl:template>
OR:
<xsl:template name="P">
<xsl:if test="name(.)='Fox'">
</xsl:if>
</xsl:template>
OR:与此相比,还有另一种更好的解决方案吗?
答案 0 :(得分:2)
我认为您会发现许多人使用[name()='Fox']
,但推荐的方式和专家使用的方法是使用self::Fox
。主要原因是当有名称空间时,name()是不可靠的,而测试namespace-uri()和local-name()的替代方法是繁琐和冗长的。此外,许多XPath引擎都有搜索具有给定名称的元素的方法,这些元素不涉及对每个元素进行字符串比较。因为对name()= Fox
的评估需要查看名称空间前缀,而不是URI,这是一种不常见的操作,它的效率也可能较低。
答案 1 :(得分:1)
首选方法是使用self
轴,因为这将处理名称空间并且更简洁。
但是,请注意,如果当前节点不是元素节点,则self
轴将无法正常工作。例如在
<xsl:template match="processing-instruction()">
<xsl:if test="self::workdir">
...
</xsl:if>
</xsl:template>
即使当前处理指令的名称为workdir
,测试也不会成功。这同样适用于更常见的情况
<xsl:template match="@*">
<xsl:if test="self::href">
...
</xsl:if>
</xsl:template>
同样,href
属性的测试将永远不会作为the principle node type for the self
axis is element。在这种情况下,您必须使用name()
或local-name()
<xsl:template match="@*">
<xsl:if test="name() = 'href'">
...
</xsl:if>
</xsl:template>
答案 2 :(得分:0)
除了第一次检查中有拼写错误之外:
<xsl:if test="self::Fox"/>
您可能还希望独立于其名称空间前缀(如果有)与节点名称进行比较。在这种情况下,您可以使用local-name()
代替name()
。
关于XPath模式我无法想象其他更简单的方法。例如,你可以这样写:
<xsl:if test="self::*[name()='test']">
但这会很荒谬。