我正在尝试解析这个示例XML文件:
<Collection version="2.0" id="74j5hc4je3b9">
<Name>A Funfair in Bangkok</Name>
<PermaLink>Funfair in Bangkok</PermaLink>
<PermaLinkIsName>True</PermaLinkIsName>
<Description>A small funfair near On Nut in Bangkok.</Description>
<Date>2009-08-03T00:00:00</Date>
<IsHidden>False</IsHidden>
<Items>
<Item filename="AGC_1998.jpg">
<Title>Funfair in Bangkok</Title>
<Caption>A small funfair near On Nut in Bangkok.</Caption>
<Authors>Anthony Bouch</Authors>
<Copyright>Copyright © Anthony Bouch</Copyright>
<CreatedDate>2009-08-07T19:22:08</CreatedDate>
<Keywords>
<Keyword>Funfair</Keyword>
<Keyword>Bangkok</Keyword>
<Keyword>Thailand</Keyword>
</Keywords>
<ThumbnailSize width="133" height="200" />
<PreviewSize width="532" height="800" />
<OriginalSize width="2279" height="3425" />
</Item>
<Item filename="AGC_1164.jpg" iscover="True">
<Title>Bumper Cars at a Funfair in Bangkok</Title>
<Caption>Bumper cars at a small funfair near On Nut in Bangkok.</Caption>
<Authors>Anthony Bouch</Authors>
<Copyright>Copyright © Anthony Bouch</Copyright>
<CreatedDate>2009-08-03T22:08:24</CreatedDate>
<Keywords>
<Keyword>Bumper Cars</Keyword>
<Keyword>Funfair</Keyword>
<Keyword>Bangkok</Keyword>
<Keyword>Thailand</Keyword>
</Keywords>
<ThumbnailSize width="200" height="133" />
<PreviewSize width="800" height="532" />
<OriginalSize width="3725" height="2479" />
</Item>
</Items>
</Collection>
这是我当前的代码:
require 'nokogiri'
doc = Nokogiri::XML(File.open("sample.xml"))
somevar = doc.css("collection")
#create loop
somevar.each do |item|
puts "Item "
puts item['Title']
puts "n"
end#items
从XML文档的根开始,我尝试从根"Collections"向下到每个新级别。
我从节点集中开始,从节点中获取信息,并且节点包含元素。如何将节点分配给变量,并提取其下的每一层和文本?
我可以执行下面的代码,但我想知道如何使用循环系统地遍历XML的每个嵌套元素,并输出每一行的数据。显示完文本后,如何移回上一个元素/节点,无论它是什么(遍历树中的节点)?
puts somevar.css("Keyworks Keyword").text
Nokogiri的NodeSet
和Node
支持非常相似的API,关键的语义差异是NodeSet
的方法倾向于依次在所有包含的节点上操作。例如,当单个节点的children
获取该节点的子节点时,NodeSet
的children
获取所有包含节点的子对象(按它们在文档中出现的顺序排列)。所以,要打印所有项目的所有标题和作者,你可以这样做:
require 'nokogiri'
doc = Nokogiri::XML(File.open("sample.xml"))
coll = doc.css("Collection")
coll.css("Items").children.each do |item|
title = item.css("Title")[0]
authors = item.css("Authors")[0]
puts title.content if title
puts authors.content if authors
end
你可以通过这种方式到达树的任何级别。另一个例子——深度优先搜索打印树中的每个节点(注意。打印的节点表示包括其子节点的打印表示,因此输出将相当长):
def rec(node)
puts node
node.children.each do |child|
rec child
end
end
由于您专门询问了这一点,如果您想了解给定节点的父节点,可以使用parent
方法。但是,如果您可以将处理放在传递给each
的块中,以及在包含感兴趣子树的NodeSet
上的类似块中,您可能永远不需要这样做。