简体   繁体   中英

Ruby Nokogiri XML Parsing for NodeSet

I'm having an issue with parsing some XML using Nokogiri in Ruby 2.6.5 . I've checked here and other posts, but I still can't seem to get the Nokogiri bit to take. I've tried different nodes, all with the same result of thing being NilClass .

require 'nokogiri'

xml_str = <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2">
  <Document>
    <description><![CDATA[powered by <a href="http://www.wordpress.org">WordPress</a> &amp; <a href="https://www.mapsmarker.com">MapsMarker.com</a>]]></description>
    <open>0</open>
    <Style id="bar"><IconStyle><Icon><href>http://epic-curiousity.com/wp-content/uploads/leaflet-maps-marker-icons/bar.png</href></Icon></IconStyle></Style>
    <name>Epic Curiousity</name>
    <Placemark id="marker-35">
      <styleUrl>#bar</styleUrl>
      <name>Brasserie de Rochefort</name>
      <TimeStamp><when>2014-06-13T07:06:01-08:00</when></TimeStamp>
      <atom:author><atom:name>epiccuri</atom:name></atom:author>
      <atom:link rel="related" href="http://epic-curiousity.com" />
      <description><![CDATA[The Brasserie de Rochefort is located inside the Abbey of Notre-Dame de Saint-Rémy in Rochefort.  They're a trappist brewery and produce three very-fine beers:<ul><li>Trappistes Rochefort 6 - Dubbel 7.5% ABV</li><li>Trappistes Rochefort 8 - Belgian Strong Dark Ale 9.2% ABV</li><li>Trappistes Rochefort 10 - Quadrupel (Quad) 11.30% ABV</li></ul>You can find the brewery's homepage here: <a href="http://www.trappistes-rochefort.com/">http://www.trappistes-rochefort.com/</a><br /><br />Their BeerAdvocate page is located here: <a href="http://www.beeradvocate.com/beer/profile/207/">http://www.beeradvocate.com/beer/profile/207/</a>]]></description>
      <address><![CDATA[Brasserie Scaillet, Rue de la Griotte, Rochefort, Belgium]]></address>
      <Point>
        <coordinates>5.199692,50.175346</coordinates>
      </Point>
    </Placemark>
  </Document>
</kml>
EOF

doc = Nokogiri::XML(xml_str)
puts doc.class                      # => Nokogiri::XML::Document
thing = doc.at_xpath("Document")
puts thing.class                    # ==> NilClass

Anybody know why this isn't being recognized as a nodeset? I've tried with this as well with the same results:

doc = Nokogiri::XML.parse(xml_str)

I see on docs that you can use css to find what you want

puts doc.at_css("Document")
# show all node Document

puts doc.css("name")
# <name>Epic Curiousity</name>
# <name>Brasserie de Rochefort</name>

puts doc.css("Placemark name")
# <name>Brasserie de Rochefort</name>

puts doc.css("Document/name")
# <name>Epic Curiousity</name>

This is due to that the xml has namespaces and these needs to be included in xpath query:

document = doc.at_xpath('//xmlns:Document')
document.class 
 => Nokogiri::XML::Element

document_name = doc.at_xpath('//xmlns:Document/xmlns:name')
document_name.class 
 => Nokogiri::XML::Element
document_name.content
 => "Epic Curiousity"

To get a name in atom:name:

atom_name = doc.at_xpath('//atom:name')
atom_name.content
 => "Epic Curiousity"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM