在模板P中检查节点的名称是否为Fox

时间:2011-06-24 04:46:47

标签: xml xslt

在模板名称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:与此相比,还有另一种更好的解决方案吗?

3 个答案:

答案 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']">

但这会很荒谬。