2013-05-30 77 views
6

有沒有辦法在節點中查找特定值,然後返回其所有兄弟值?使用Nokogiri獲取節點的兄弟節點

例如,我想找到找到包含ID 5678 id節點,然後獲得的電子郵件地址和ID 5678

Nokogiri::XML.parse(File.open('info.xml')) 

相關聯的所有圖像下面是一個示例XML文件。

<xmlcontainer> 
    <details> 
    <id>1234</id> 
    <email>[email protected]</email> 
    <image>images/1.jpg</image> 
    <image>images/2.jpg</image> 
    <image>images/3.jpg</image> 
    </details> 
    <details> 
    <id>5678</id> 
    <email>[email protected]</email> 
    <image>images/4.jpg</image> 
    <image>images/5.jpg</image> 
    </details> 
    <details> 
    <id>9011</id> 
    <email>[email protected]</email> 
    <image>images/6.jpg</image> 
    <image>images/7.jpg</image> 
    </details> 
</xmlcontainer> 

回答

3
require 'nokogiri' 
doc = Nokogiri::XML.parse(File.open('info.xml')) 
details = doc.css('details').find{|node| node.css('id').text == "5678"} 
email = details.css('email').text # => "[email protected]" 
images = details.css('image').map(&:text) # => ["images/4.jpg", "images/5.jpg"] 

更新:有短,可以說是更好的,方法來抓住你想要的details節點:

details = doc.at('details:has(id[text()="5678"])') 

details = doc.search('id[text()="5678"] ~ *') 

這些都是雙方禮貌pguardiario。

+1

您可以通過用'find {}'替換'select {}。first'來加強它,或者您可以更直接地通過'doc.at('details:has(id [text()= 「5678」])')' – pguardiario

+0

@pguardiario搜索文檔的很多方法!感謝您的提示! –

+2

不客氣!在這種情況下,xpath實際上可能會更簡單:'doc.at('// id [text()='5678「]/..')' – pguardiario

6

您可以使用~,這是CSS一般兄弟選擇:

doc.search('id[text()="5678"] ~ *').map &:text 
#=> ["[email protected]", "images/4.jpg", "images/5.jpg"] 

這很奇怪使用CSS與XML一點點,但它是如此容易得多看看(比XPath的)。

+0

非常好的語法''id [text()=「5678」]〜*''。第一次,我基本上找到了'XPATH'部分,就像'[text()=「5678」]'。你在哪裏見過這樣的伎倆? :)如果可能請解釋搜索表達式。 –

+0

'[text()=「5678」]不是標準的CSS,但nokogiri允許。其餘的只是CSS。 '〜*'表示任何兄弟元素 – pguardiario

+0

+1「在xml中使用css有些奇怪,但它比xpath更容易查看(比xpath)。」我同意,我很高興Nokogiri給了我們這個選擇。 CSS通常更具可讀性。 –

相關問題