Getting siblings node with nokogiri

Is there a way to find a specific value in node and then return all its sibling values?

For example, I would like to find an id node that contains ID 5678, and then get the email address and all the images associated with ID 5678.

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

Here is an example XML file.

 <xmlcontainer> <details> <id>1234</id> <email> sdfsdf@sdasd.com </email> <image>images/1.jpg</image> <image>images/2.jpg</image> <image>images/3.jpg</image> </details> <details> <id>5678</id> <email> zzzz@zzz.com </email> <image>images/4.jpg</image> <image>images/5.jpg</image> </details> <details> <id>9011</id> <email> aaaa@aaa.com </email> <image>images/6.jpg</image> <image>images/7.jpg</image> </details> </xmlcontainer> 
+6
source share
2 answers
 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 # => " zzzz@zzz.com " images = details.css('image').map(&:text) # => ["images/4.jpg", "images/5.jpg"] 

Update: There are shorter, perhaps better ways to capture the details node you want:

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

or

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

Both are courtesy of pguardiario.

+3
source

You can use ~ , which is a common css selector:

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

It is a little strange to use css with xml, but it is much easier to watch (than xpath).

+6
source

Source: https://habr.com/ru/post/946145/


All Articles