检查属性等于value的节点是否存在

时间:2011-12-07 07:41:08

标签: xslt if-statement

我有以下XSLT变量:

<xsl:variable name="superid" select="/contentdata/id"/>

此外,我有一个带子节点的节点:

<nodes>
    <node name="foo" id="bar" />
    <node name="john" id="doe" />
    <node name="jane" id="tarzan" />
</nodes>

现在,我想检查一个id属性等于superid的节点是否存在。

我尝试了以下(显然不起作用):

<xsl:if test="/nodes/node[@id = $superid]">Yes, Sir!</xsl:if>

4 个答案:

答案 0 :(得分:15)

使用

boolean(/nodes/node/@id = $superid)

这是一个完整的转换,显示了这一点

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vDoe" select="'doe'"/>
 <xsl:variable name="vXyz" select="'xyz'"/>

 <xsl:template match="/">
     id attribute with value "doe' exists: <xsl:text/>
     <xsl:value-of select="boolean(/nodes/node/@id = $vDoe)"/>
==========
     id attribute with value "xyz' exists: <xsl:text/>
     <xsl:value-of select="boolean(/nodes/node/@id = $vXyz)"/>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档

<nodes>
    <node name="foo" id="bar" />
    <node name="john" id="doe" />
    <node name="jane" id="tarzan" />
</nodes>

产生了想要的正确结果

     id attribute with value "doe' exists: true
==========
     id attribute with value "xyz' exists: false

答案 1 :(得分:4)

根据here,您似乎对我有用(.Net 3.5)。

我尝试重新创建您的xslt

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                >
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" />

    <xsl:template match="/xml">
        <xml>
            <xsl:apply-templates select="contentdata/id" />
        </xml>
    </xsl:template>

    <xsl:template match="id">
        <Result>
        <xsl:variable name="superid" select="."/>
        <SearchFor>
            <xsl:value-of select="$superid"/>
        </SearchFor>
        <IsPresent>
            <xsl:if test="/xml/nodes/node[@id = $superid]">Node is present</xsl:if>
        </IsPresent>
    </Result>
    </xsl:template>

</xsl:stylesheet>

给出xml:

<xml>
    <contentdata>
        <id>doe</id>
        <id>unobtanium</id>
    </contentdata>
    <nodes>
        <node name='foo' id='bar' />
        <node name='john' id='doe' />
        <node name='jane' id='tarzan' />
    </nodes>
</xml>

输出:

<xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Result>
        <SearchFor>doe</SearchFor>
        <IsPresent>Node is present</IsPresent>
    </Result>
    <Result>
        <SearchFor>unobtanium</SearchFor>
        <IsPresent />
    </Result>
</xml>

答案 2 :(得分:3)

如果您使用xpath表达式 / nodes / node [@id = $ superid]“&gt; ,那么这将寻找节点的根节点您的XML文档。但是,在您的问题中,您似乎暗示节点只是文档中的一个节点,而不一定是根元素。请尝试使用

<xsl:if test="//nodes/node[@id = $superid]">Yes, Sir!</xsl:if>

双斜杠选择文档中的节点,无论它们位于层次结构中,而不仅仅是顶级节点。

答案 3 :(得分:1)

这应该按照您的预期运作。您的一个表达式(在变量的selecttest属性中)不能选择您认为的表达式。 (你没有提供完整的输入,因此很难在那里提供帮助。)

请注意xsl:if

的一些内容
  • 首先,请参阅this part of the XSLT spec(强调我自己):

      

    xsl:if元素有一个test属性,用于指定   表达。内容是一个模板。表达式被评估和   结果对象转换为布尔值,就好像通过调用一样   布尔函数。如果结果为true,则内容模板为   实例化;否则,什么都没有创造。

  • 那么如何调用boolean函数对您的输入有效?见this part of the XPath spec(再次,强调我的):

      

    布尔函数将其参数转换为布尔值,如下所示:

         
        
    • 当且仅当它既不是正零或负零也不是NaN

    • 时,数字为真   
    • 当且仅当非空时,节点集为真

    •   
    • 当且仅当其长度为非零

    • 时,该字符串为真   
    • 除了四种基本类型之外的类型的对象将以依赖于该类型的方式转换为布尔值

    •   

因此,如果/contentdata/id实际选择了id /nodes/node[@id = $superid]返回非空节点集,那么xsl:if的正文应该执行。