2011-12-07 110 views
10

我有以下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> 
+0

什麼是$ superid變量值? – Vitaliy

+0

你得到的錯誤信息是什麼?我相信它可能是.NET版本,而您使用的是xslt v1或v2。請給我們這些信息。創建一個小提琴,而你在它:) –

回答

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 
4

你有什麼似乎爲我(.NET 3.5)工作 - 按here

我試圖重新創建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> 
3

如果使用XPath表達式/節點/ node [@id = $ superid]「>那麼這將是看起來ng爲您的XML文檔中的根節點節點。但是,在您的問題中,您似乎暗示節點只是您文檔中的一個節點,不一定是根元素。試試這個代替

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

雙斜槓選擇文檔中的任何節點,而不僅僅是它們在層次結構中的節點,而不僅僅是頂級節點。

1

像您期望這應該是工作。您的一個表達式(在變量的selecttest屬性中)不能選擇您認爲的內容。 (你沒有提供完整的輸入,所以很難在這裏提供幫助。)

備註xsl:if幾件事情:

  • 首先,看看this part of the XSLT spec(強調我自己):

    了xsl:if元素有一個測試的屬性,它指定一個 表達。內容是一個模板。評估該表達式並且 結果對象被轉換爲布爾值,就好像通過調用 布爾函數。如果結果爲真,那麼實例化內容模板 ;否則,不會創建任何內容。

  • 那麼如何調用boolean函數來處理您的輸入?見this part of the XPath spec(再次,重點煤礦):

    布爾函數將其參數轉換爲布爾如下:如果,如果它僅僅是

    • 一些是真的既不是正或負零,也不NaN的

    • 節點集是當且僅當它是非空

    • 串真爲真,當且僅當其長度爲非零

    • 比四種基本類型以外的類型的對象被轉換成布爾的方式,依賴於該類型

所以,如果/contentdata/id實際選擇一個id爲其/nodes/node[@id = $superid]返回一個非空的節點集,則xsl:if的主體應執行。