2011-08-26 154 views
1
<parents> 
<parent> 
    <item> 
     <name>200</name> 
    </item> 
    <item> 
     <name>201</name> 
    </item> 
    <item> 
     <name>204</name> 
    </item> 
</parent> 
<parent> 
    <item> 
     <name>203</name> 
    </item> 
</parent> 
</parents> 

我需要第一個parent節點,因爲我有一個與項目對應的ID列表。試想一下:如何根據多個子節點值獲取父節點?

list = ['200', '201']; 

因爲200在第一parent節點被發現,我想要那個parent節點。如果200不存在,我仍然會得到父節點,因爲201是位於第一個parent中的/name/text()的值。

我的唯一要求是我需要抓住parent節點,如果發現我的list中的ID爲one

目前我只測試爲先,就像這樣:

//name/child::text()[.="' . $firstKey . '"]/../../../../

$firstKey是在列表中,200的第一個元素的引用。這並不理想,因爲它不檢查所有值,但只檢查第一個值。

+0

好問題,+1。查看我對兩種解決方案的回答 - 一個XPath 1.0 + XSLT解決方案和一個XPath 2.0解決方案 –

回答

1

I. XPath 1.0中使用XSLT 1溶液。0作爲主機

用途:

/*/parent[item/name = $vList] 

這種轉變

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<my:list> 
    <val>200</val> 
    <val>201</val> 
</my:list> 

<xsl:variable name="vList" select= 
    "document('')/*/my:list/*"/> 

<xsl:template match="/"> 
    <xsl:copy-of select="*/parent[item/name = $vList]"/> 
</xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<parents> 
    <parent> 
     <item> 
      <name>200</name> 
     </item> 
     <item> 
      <name>201</name> 
     </item> 
     <item> 
      <name>204</name> 
     </item> 
    </parent> 
    <parent> 
     <item> 
      <name>203</name> 
     </item> 
    </parent> 
</parents> 

產生想要的,正確的結果

<parent> 
    <item> 
     <name>200</name> 
    </item> 
    <item> 
     <name>201</name> 
    </item> 
    <item> 
     <name>204</name> 
    </item> 
</parent> 

注意:您可以通過現在<my:list>什麼作爲參數的轉變。

二,使用XPath 2.0

/*/parent[item/name = ('200', '201')] 

的XSLT 2.0 - 基於驗證低於」

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/"> 
    <xsl:copy-of select="*/parent[item/name = ('200', '201')]"/> 
</xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔(上文)施加相同的正確的結果被產生。

+0

看起來像'('200','201')在逗號當使用這個不是在XSLT的上下文中,而是在各種語言中的XPATH接口?這是否意味着他們沒有使用xpath 2.0,還是僅在XSLT環境中有效? –

+0

@meder:這是標準的XPath 2.0 - 任何XPath 2.0引擎都支持這一點。例如,這在XQuery中是有效的,因爲XQuery是XPath 2.0的超集。因此,要回答這個問題,如果給定的XPath引擎無法評估此表達式(並且很可能引發語法錯誤),這意味着它不支持XPath 2.0。 –

+0

是啊,呃... –

0

像這樣的東西可能會有所幫助:

//parent[.//item[name[text()='200' or text()='201']]] 

你必須構建最裏面的謂詞(與text()='200' or ...)編程,雖然。我不確定你使用的是哪種上下文,但是由於你使用了一個變量引用,所以我假設了XSLT。我會看看有沒有什麼更適合...

編輯:我能想到的唯一的事情是連接所有你的鑰匙一些符號,你是相信他們會不會包含作爲分隔符。例如:

200#201#... 

然後使用XPath contains功能:

//parent[.//item[name[contains('200#201#...', normalize-space(text()))]]] 

的則包含必須是你的級聯鍵,或許傳過來的變量的第一個參數。函數string-join對此很有用,但我相信它僅在XPath 2.0中可用。

0

如果你有XSLT 2.0,你可以說

<xsl:variable name="list" select="(200, 201)" /> 
<xsl:variable name="theParent" select="(//parent[item/name = $list])[1]" /> 

=作品的存在主義比較,返回true,如果在左側的節點集的任何產品上的序列中等於任何項目=的右側。

(未測試)