我正在用Nokogiri解析一个XML文件,代码片段如下:
doc.xpath('//root').each do |root|
puts "# ROOT found"
root.xpath('//page').each do |page|
puts "## PAGE found / #{page['id']} / #{page['name']} / #{page['width']} / #{page['height']}"
page.children.each do |content|
...
end
end
end
如何解析页面元素中的所有元素?有三种不同的元素:图像、文本和视频。如何为每个元素创建case语句?
老实说,你看起来离我很近。
doc.xpath('//root').each do |root|
puts "# ROOT found"
root.xpath('//page').each do |page|
puts "## PAGE found / #{page['id']} / #{page['name']} / #{page['width']} / #{page['height']}"
page.children.each do |child|
case child.name
when 'image'
do_image_stuff
when 'text'
do_text_stuff
when 'video'
do_video_stuff
end
end
end
end
Nokogiri的CSS和XPath访问器都允许指定多个标记,这对于这类问题很有用。而不是遍历文档的page
标记中的每个标记:
require 'nokogiri'
doc = Nokogiri::XML('
<xml>
<body>
<image>image</image>
<text>text</text>
<video>video</video>
<other>other</other>
<image>image</image>
<text>text</text>
<video>video</video>
<other>other</other>
</body>
</xml>')
这是一个使用CSS的搜索:
doc.search('image, text, video').each do |node|
case node.name
when 'image'
puts node.text
when 'text'
puts node.text
when 'video'
puts node.text
else
puts 'should never get here'
end
end
# >> image
# >> image
# >> text
# >> text
# >> video
# >> video
注意,它按照CSS访问器指定的顺序返回标签。如果需要文档中标记的顺序,可以使用XPath:
doc.search('//image | //text | //video').each do |node|
puts node.text
end
# >> image
# >> text
# >> video
# >> image
# >> text
# >> video
无论哪种情况,程序都应该运行得更快,因为所有搜索都在libXML中进行,只返回Ruby处理所需的节点。
如果你需要将搜索限制在<page>
标签内,你可以在前面搜索找到page
节点,然后在它下面搜索:
doc.at('page').search('image, text, video').each do |node|
...
end
或
doc.at('//page').search('//image | //text | //video').each do |node|
...
end