2011-12-18 12 views
8

Với XML này trong một chuỗi gọi là "chuỗi":Làm thế nào tôi có thể lặp qua các nút con của một tên cụ thể trong một Tài liệu XML Nokogiri?

<Guide> 
    <Master> 
    <Part>12345</Part> 
    <Sub> 
     <Name>A</Name> 
    </Sub> 
    <Sub> 
     <Name>B</Name> 
    </Sub> 
    </Master> 
    <Master> 
    <Part>XYZABC</Part> 
    <Sub> 
     <Name>A</Name> 
    </Sub> 
    <Sub> 
     <Name>C</Name> 
    </Sub> 
    </Master> 
</Guide> 

Và dòng mã này:

bgdoc = Nokogiri::XML::DocumentFragment.parse(xstring.to_xml) 

Tôi muốn lặp qua tất cả các nút có tên là "Phần".

tôi thử như sau:

bgdoc.xpath("//Part").each do |node| 

và:

bgdoc.children.each do |node| 
    next unless node.name=="Part" 

Nhưng điều đó không làm việc.

Trả lời

8

Vấn đề là phân tích cú pháp XML như là một đoạn trả về một tài liệu XML một phần, ví dụ, một DocumentFragment, mà không có một gốc:

1.9.2-p290 :002 > doc = Nokogiri::XML::DocumentFragment.parse('<a><b>foo</b></a>').root 
NoMethodError: undefined method `root' for #<Nokogiri::XML::DocumentFragment:0x00000100b34448> 
    from (irb):2 
    from /Users/greg/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>' 

trong khi một tài liệu đầy đủ XML không có một gốc:

1.9.2-p290 :003 > doc = Nokogiri::XML('<a><b>foo</b></a>').root 
=> #<Nokogiri::XML::Element:0x8058b350 name="a" children=[#<Nokogiri::XML::Element:0x80587b10 name="b" children=[#<Nokogiri::XML::Text:0x80587818 "foo">]>]> 

Theo mặc định Nokogiri sẽ tìm kiếm từ thư mục gốc của tài liệu với XPath như //Path:

1.9.2-p290 :004 > doc = Nokogiri::XML('<a><Path>foo</Path></a>').search('//Path') 
=> [#<Nokogiri::XML::Element:0x8055465c name="Path" children=[#<Nokogiri::XML::Text:0x805543c8 "foo">]>] 

Nhưng điều đó không thành công với đoạn vì gốc còn thiếu:

1.9.2-p290 :005 > doc = Nokogiri::XML::DocumentFragment.parse('<a><Path>foo</Path></a>').search('//Path') 
=> [] 

Bí quyết là để nói Nokogiri nơi để xem xét khi giao dịch với các mảnh vỡ. Sử dụng một tìm kiếm thân nhân hoặc một ký tự đại diện:

1.9.2-p290 :006 > doc = Nokogiri::XML::DocumentFragment.parse('<a><Path>foo</Path></a>').search('.//Path') 
=> [#<Nokogiri::XML::Element:0x8053c69c name="Path" children=[#<Nokogiri::XML::Text:0x8053c46c "foo">]>] 

hoặc

1.9.2-p290 :007 > doc = Nokogiri::XML::DocumentFragment.parse('<a><Path>foo</Path></a>').search('*//Path') 
=> [#<Nokogiri::XML::Element:0x8052a208 name="Path" children=[#<Nokogiri::XML::Text:0x80529fec "foo">]>] 
0
bgdoc.css("Part") 

nên thực hiện công việc.

1
bgdoc = Nokogiri::XML::DocumentFragment.parse(<<EOF) 
    <xml stuff> 
EOF 

bgdoc.xpath(".//Part").each do |node| 
    # some instruction 
end 
1

Nếu bạn có chỉ là một chuỗi, chỉ cần phân tích với Nokogiri:XML thay vì:

bgdoc = Nokogiri::XML.parse(string) 

sẽ cung cấp cho bạn một gốc từ bạn có thể sử dụng xpath //Part như bạn mong đợi.

Các vấn đề liên quan