2013-07-11 35 views
10

Tôi đang gặp một số vấn đề với Nokogiri.Làm cách nào để sử dụng Nokogiri để phân tích cú pháp tệp XML?

Tôi cố gắng để phân tích file XML này:

<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> 

Tôi muốn tất cả các thông tin mà hiển thị ra màn hình, đó là nó. Nên đơn giản đúng không? tôi đang làm điều này:

require 'nokogiri' 

doc = Nokogiri::XML(File.open("sample.xml")) 
@block = doc.css("items item").map {|node| node.children.text} 
puts @block 

Mỗi Items là một nút, và dưới đó có trẻ em nút của Item?

Tôi tạo bản đồ về điều này, trả về giá trị băm và mã trong {} đi qua từng nút và đặt văn bản cho trẻ em vào @block. Sau đó, tôi có thể hiển thị tất cả văn bản của nút con tới màn hình.

Tôi không biết mình đang ở xa đến mức nào, bởi vì tôi đã đọc rất nhiều bài báo, và vẫn còn hơi bối rối về những điều cơ bản, đặc biệt là từ một ngôn ngữ mới, tôi đọc từ một tệp và xuất ra màn hình cho một chương trình cơ bản.

+0

Nếu bạn có bất kỳ câu hỏi cụ thể nào, hãy cho tôi biết. Tôi sẽ phản hồi. –

+0

Tôi có một câu hỏi khác. http: // stackoverflow.com/questions/17600037/using-nokogiri-to-parse-xml-file Đó là về cách đi qua cây nút. – camdixon

+0

các điểm câu hỏi được liên kết đến bài đăng này. –

Trả lời

26

Ở đây tôi sẽ cố gắng giải thích cho bạn tất cả các câu hỏi/nhầm lẫn bạn đang gặp:

require 'nokogiri' 

doc = Nokogiri::XML.parse <<-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> 
XML 

Vì vậy, từ sự hiểu biết của tôi về Nokogiri, mỗi 'Mặt hàng' là một nút, và dưới đó có các nút con của 'Mục'?

Không, mỗi MụcNokogiri::XML::NodeSet. Và dưới đó có 2 nút con của Các mục, là đối tượng lớp học Nokogiri::XML::Element. Bạn có thể nói họ cũng Nokogiri::XML::Node

doc.class # => Nokogiri::XML::Document 
@block = doc.xpath("//Items/Item") 
@block.class # => Nokogiri::XML::NodeSet 
@block.count # => 2 
@block.map { |node| node.name } 
# => ["Item", "Item"] 
@block.map { |node| node.class } 
# => [Nokogiri::XML::Element, Nokogiri::XML::Element] 
@block.map { |node| node.children.count } 
# => [19, 19] 
@block.map { |node| node.class.superclass } 
# => [Nokogiri::XML::Node, Nokogiri::XML::Node] 

Chúng tôi tạo ra một bản đồ này, mà trả về một băm Tôi tin, và các mã trong {} đi qua mỗi nút và hiển thị chữ trẻ em vào @block . Sau đó, tôi có thể hiển thị tất cả văn bản của nút con này trên màn hình.

Tôi không hiểu điều này. Mặc dù tôi đã cố gắng giải thích dưới đây để hiển thị những gì là Nút và những gì là Nodeset trong Nokogiri. Hãy nhớ Nodeset là một bộ sưu tập của Nút.

@chld_class = @block.map do |node| 
    node.children.class 
end 
@chld_class 
# => [Nokogiri::XML::NodeSet, Nokogiri::XML::NodeSet] 
@chld_name = @block.map do |node| 
    node.children.map { |n| [n.name,n.class] } 
end 
@chld_name 
# => [[["text", Nokogiri::XML::Text], 
#  ["Title", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["Caption", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["Authors", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["Copyright", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["CreatedDate", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["Keywords", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["ThumbnailSize", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["PreviewSize", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["OriginalSize", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text]], 
#  [["text", Nokogiri::XML::Text], 
#  ["Title", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["Caption", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["Authors", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["Copyright", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["CreatedDate", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["Keywords", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["ThumbnailSize", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["PreviewSize", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text], 
#  ["OriginalSize", Nokogiri::XML::Element], 
#  ["text", Nokogiri::XML::Text]]] 

@chld_name = @block.map do |node| 
    node.children.map{|n| [n.name,n.text.strip] if n.elem? }.compact 
end.compact 
@chld_name 
# => [[["Title", "Funfair in Bangkok"], 
#  ["Caption", "A small funfair near On Nut in Bangkok."], 
#  ["Authors", "Anthony Bouch"], 
#  ["Copyright", "Copyright © Anthony Bouch"], 
#  ["CreatedDate", "2009-08-07T19:22:08"], 
#  ["Keywords", "Funfair\n  Bangkok\n  Thailand"], 
#  ["ThumbnailSize", ""], 
#  ["PreviewSize", ""], 
#  ["OriginalSize", ""]], 
#  [["Title", "Bumper Cars at a Funfair in Bangkok"], 
#  ["Caption", "Bumper cars at a small funfair near On Nut in Bangkok."], 
#  ["Authors", "Anthony Bouch"], 
#  ["Copyright", "Copyright © Anthony Bouch"], 
#  ["CreatedDate", "2009-08-03T22:08:24"], 
#  ["Keywords", 
#  "Bumper Cars\n  Funfair\n  Bangkok\n  Thailand"], 
#  ["ThumbnailSize", ""], 
#  ["PreviewSize", ""], 
#  ["OriginalSize", ""]]] 
+0

Câu trả lời hay! (y) –

+0

@LuizDamimn Cảm ơn Man! –

4

Các nút trong XML mẫu được vốn, do đó, mã của bạn nên phản ánh điều đó. Ví dụ:

require 'nokogiri' 

doc = Nokogiri::XML(File.open("sample.xml")) 
@block = doc.css("Items Item").map { |node| node.children.text } 
puts @block 
Các vấn đề liên quan