2013-07-12 39 views
0

我试图解析这个示例XML文件:如何使用循环解析Nokogiri css选择器的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文档的根开始,我试图从根本上走“收藏”下降到每个新的水平。

我从节点集开始,并从节点获取信息,节点包含元素。如何将节点分配给变量,并提取该文本下面的每个图层?

我可以做类似下面的代码,但我想知道如何系统地移动XML的每个嵌套元素使用循环,并输出每行的数据。完成显示文本后,如何返回到上一个元素/节点,无论它是什么(遍历树中的节点)?

puts somevar.css("Keyworks Keyword").text 
+0

那么当你解析XML时你想捕获什么?解析它并遍历它很好,但我们需要知道你实际上想要完成什么。 –

+0

结帐这个sax解析选项,http://amolnpujari.wordpress.com/2012/03/31/reading_huge_xml-rb/新的OX ruby​​解析器似乎比Nokogiri快5倍,https://gist.github.com/ amolpujari/5966431 –

回答

0

引入nokogiri的NodeSetNode支持非常相似的API,关键语义差别在于NodeSet的方法往往会反过来所包含的所有节点上运行。例如,当单个节点的children获取该节点的子节点时,NodeSetchildren将获取所有包含节点的子节点(按文档中出现的顺序排列)。因此,打印所有的标题和所有项目的作者,你可以这样做:

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 

您可以在树这样的任何级别得到。另一个例子 - 深度优先搜索打印每一个节点树(NB节点的印刷表示包括其子女的印刷陈述,所以输出将是相当长的。):

def rec(node) 
    puts node 
    node.children.each do |child| 
    rec child 
    end 
end 

既然你问关于这一点,如果您想要查看给定节点的父节点,则可以使用parent方法。不过,如果您可以将处理过程传递给each等包含感兴趣子树的NodeSet,您可能永远不需要。

+0

Michal, 你的回答真的帮了我很大的忙:) 现在唯一让我绊倒的是你如何从给定的标签中选择一个属性。 例如,在一些标签上,我们有“宽度”和“高度” 如何获得那些使用您的代码的价值? – camdixon

+0

有许多从节点中提取属性的方法;例如,'attributes'会得到一个属性和值的哈希值(名称空间从属性中剥离;如果这是个问题,请参阅'attribute_nodes'),'each'遍历属性名称/值对(直接位于节点,而不是'children'的返回值等)。有关详细信息,请参阅[Nokogiri :: XML :: Node的API文档](http://nokogiri.org/Nokogiri/XML/Node.html)。 –