开发者

checking if the name of a node is Fox within a template P

In a template name P, i want to check if the name of the current node is Fox. I'm wondering what's the 开发者_如何转开发usual way that people do to do this kind of checks:

<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: is there another better solution compared to this 2?


I think you will find that many people use [name()='Fox'] but the recommended way, and the way used by experts, is to use self::Fox. The main reason for that is that name() is unreliable when there are namespaces around, and the alternative of testing both namespace-uri() and local-name() is cumbersome and verbose. Also, many XPath engines have ways of searching for an element with a given name that don't involve doing string comparisons on every element. Because evaluation of name()=Fox requires looking at the namespace prefix, not the URI, which is an uncommon operation, it's also likely to be less efficient.


The preferred approach is to use the self axis as this will take care of namespaces and is more terse.

Note, however, that if your current node is not an element node, the self axis will not work as you might expect. For example in

<xsl:template match="processing-instruction()">
  <xsl:if test="self::workdir">
    ...
  </xsl:if>
</xsl:template>

The test will never succeed, even if the current processing instruction has the name workdir. The same applies to more common case

<xsl:template match="@*">
  <xsl:if test="self::href">
    ...
  </xsl:if>
</xsl:template>

Again, the test for href attribute will never work as the principle node type for the self axis is element. In this case you have to use name() or local-name()

<xsl:template match="@*">
  <xsl:if test="name() = 'href'">
    ...
  </xsl:if>
</xsl:template>


Apart the fact that there is a typo in the first check:

 <xsl:if test="self::Fox"/>

You might want also compare against the node name independently from its namespace prefix (if any). In that case you can use local-name() in place of name().

About the XPath pattern I can't imagine other ways much simpler. For instance, you can write something like this:

<xsl:if test="self::*[name()='test']">

But it's going to be ridiculous.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜