1

Nokogiri または ReXML を使用して GPX ファイルを解析しようとしていますが、とても簡単に思えてうまくいきません。空の配列またはnil「未定義」の出力が常に得られますが、それで問題ないと確信しています。髪を引っ張っています。誰かがそれを行う方法を教えてもらえますか? latlonおよびele値を使用してポイントを抽出し、きれいなハッシュの配列にしたいと思います。

XML は次のとおりです (さらに多くのポイントがあります)。

<?xml version="1.0"?>
<gpx creator="GPS Visualizer http://www.gpsvisualizer.com/" version="1.0" xmlns="http://www.topografix.com/GPX/1/0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
<trk>
  <name>20090426-144136</name>
  <trkseg>
    <trkpt lat="54.0663350" lon="-2.0050000">
      <ele>171.1</ele>
    </trkpt>
    <trkpt lat="54.0663400" lon="-2.0050000">
      <ele>172.8</ele>
    </trkpt>
    <trkpt lat="54.0663380" lon="-2.0049970">
      <ele>172</ele>
    </trkpt>
  </trkseg>
</trk>
</gpx>

そして、これは私が取得したいものです:

:route => [{ :lat => 54.0663350, :lon => -2.0050000, :ele => 171.1 },
 { :lat => 54.0663400, :lon => -2.0050000, :ele => 172.8 }, ...]

または同様のもの(より良い提案がある場合)。

最終的に、データは JSON として送信され、JavaScript の Google マップでルートが表示されます。ただし、データベースにシリアル化されたハッシュとして保存して、単一のポイントを照会できるようにしたいと考えています。

これは、ノコギリで頭を悩ませた瞬間の1つです。

1.9.3p194 :179 > doc = Nokogiri::XML(File.open("gpx/short.gpx"))
 => #<Nokogiri::XML::Document:0x816dbe34 name="document" children=[#<Nokogiri::XML::Element:0x816dba38 name="gpx" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> attributes=[#<Nokogiri::XML::Attr:0x816db948 name="creator" value="GPS Visualizer http://www.gpsvisualizer.com/">, #<Nokogiri::XML::Attr:0x816db934 name="version" value="1.0">, #<Nokogiri::XML::Attr:0x816db920 name="schemaLocation" namespace=#<Nokogiri::XML::Namespace:0x816dad40 prefix="xsi" href="http://www.w3.org/2001/XMLSchema-instance"> value="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">] children=[#<Nokogiri::XML::Text:0x816da3f4 "\n">, #<Nokogiri::XML::Element:0x816da278 name="trk" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d9da0 "\n  ">, #<Nokogiri::XML::Element:0x816d9c60 name="name" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d95a8 "20090426-144136">]>, #<Nokogiri::XML::Text:0x816d9148 "\n  ">, #<Nokogiri::XML::Element:0x816d901c name="trkseg" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d8a7c "\n    ">, #<Nokogiri::XML::Element:0x816d898c name="trkpt" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> attributes=[#<Nokogiri::XML::Attr:0x816d8928 name="lat" value="54.0663350">, #<Nokogiri::XML::Attr:0x816d8914 name="lon" value="-2.0050000">] children=[#<Nokogiri::XML::Text:0x816d7a3c "\n      ">, #<Nokogiri::XML::Element:0x816d7938 name="ele" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d7370 "171.1">]>, #<Nokogiri::XML::Text:0x816d712c "\n    ">]>, #<Nokogiri::XML::Text:0x816d6e0c "\n    ">, #<Nokogiri::XML::Element:0x816d6ccc name="trkpt" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> attributes=[#<Nokogiri::XML::Attr:0x816d6c54 name="lat" value="54.0663400">, #<Nokogiri::XML::Attr:0x816d6bf0 name="lon" value="-2.0050000">] children=[#<Nokogiri::XML::Text:0x816d5db8 "\n      ">, #<Nokogiri::XML::Element:0x816d5cb4 name="ele" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d57c8 "172.8">]>, #<Nokogiri::XML::Text:0x816d5430 "\n    ">]>, #<Nokogiri::XML::Text:0x816d500c "\n    ">, #<Nokogiri::XML::Element:0x816d4eb8 name="trkpt" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> attributes=[#<Nokogiri::XML::Attr:0x816d4e54 name="lat" value="54.0663380">, #<Nokogiri::XML::Attr:0x816d4e40 name="lon" value="-2.0049970">] children=[#<Nokogiri::XML::Text:0x816d41e8 "\n      ">, #<Nokogiri::XML::Element:0x816d40a8 name="ele" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816bafe0 "172">]>, #<Nokogiri::XML::Text:0x816bacd4 "\n    ">]>, #<Nokogiri::XML::Text:0x816ba9c8 "\n  ">]>, #<Nokogiri::XML::Text:0x816ba734 "\n">]>, #<Nokogiri::XML::Text:0x816ba4c8 "\n">]>]> 
1.9.3p194 :205 > doc.xpath("*")
 => [#<Nokogiri::XML::Element:0x816dba38 name="gpx" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> attributes=[#<Nokogiri::XML::Attr:0x816db948 name="creator" value="GPS Visualizer http://www.gpsvisualizer.com/">, #<Nokogiri::XML::Attr:0x816db934 name="version" value="1.0">, #<Nokogiri::XML::Attr:0x816db920 name="schemaLocation" namespace=#<Nokogiri::XML::Namespace:0x816dad40 prefix="xsi" href="http://www.w3.org/2001/XMLSchema-instance"> value="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">] children=[#<Nokogiri::XML::Text:0x816da3f4 "\n">, #<Nokogiri::XML::Element:0x816da278 name="trk" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d9da0 "\n  ">, #<Nokogiri::XML::Element:0x816d9c60 name="name" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d95a8 "20090426-144136">]>, #<Nokogiri::XML::Text:0x816d9148 "\n  ">, #<Nokogiri::XML::Element:0x816d901c name="trkseg" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d8a7c "\n    ">, #<Nokogiri::XML::Element:0x816d898c name="trkpt" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> attributes=[#<Nokogiri::XML::Attr:0x816d8928 name="lat" value="54.0663350">, #<Nokogiri::XML::Attr:0x816d8914 name="lon" value="-2.0050000">] children=[#<Nokogiri::XML::Text:0x816d7a3c "\n      ">, #<Nokogiri::XML::Element:0x816d7938 name="ele" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d7370 "171.1">]>, #<Nokogiri::XML::Text:0x816d712c "\n    ">]>, #<Nokogiri::XML::Text:0x816d6e0c "\n    ">, #<Nokogiri::XML::Element:0x816d6ccc name="trkpt" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> attributes=[#<Nokogiri::XML::Attr:0x816d6c54 name="lat" value="54.0663400">, #<Nokogiri::XML::Attr:0x816d6bf0 name="lon" value="-2.0050000">] children=[#<Nokogiri::XML::Text:0x816d5db8 "\n      ">, #<Nokogiri::XML::Element:0x816d5cb4 name="ele" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816d57c8 "172.8">]>, #<Nokogiri::XML::Text:0x816d5430 "\n    ">]>, #<Nokogiri::XML::Text:0x816d500c "\n    ">, #<Nokogiri::XML::Element:0x816d4eb8 name="trkpt" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> attributes=[#<Nokogiri::XML::Attr:0x816d4e54 name="lat" value="54.0663380">, #<Nokogiri::XML::Attr:0x816d4e40 name="lon" value="-2.0049970">] children=[#<Nokogiri::XML::Text:0x816d41e8 "\n      ">, #<Nokogiri::XML::Element:0x816d40a8 name="ele" namespace=#<Nokogiri::XML::Namespace:0x816db970 href="http://www.topografix.com/GPX/1/0"> children=[#<Nokogiri::XML::Text:0x816bafe0 "172">]>, #<Nokogiri::XML::Text:0x816bacd4 "\n    ">]>, #<Nokogiri::XML::Text:0x816ba9c8 "\n  ">]>, #<Nokogiri::XML::Text:0x816ba734 "\n">]>, #<Nokogiri::XML::Text:0x816ba4c8 "\n">]>] 
1.9.3p194 :206 > doc.xpath("*/trk")
 => [] 
1.9.3p194 :207 > doc.xpath("//trk")
 => [] 
1.9.3p194 :208 > doc.xpath("trk")
 => [] 
1.9.3p194 :209 > doc.xpath("//trkpt")
 => []
1.9.3p194 :210 > doc.xpath("*/gpx")
 => [] 
1.9.3p194 :211 > doc.xpath("*/gpx/trk")
 => [] 

私は何を間違っていますか?

4

1 に答える 1

1

「 RubyGPXファイルパーサー」の助けを借りて、問題を発見しました。XMLタグの名前空間を宣言する必要がありました:doc.xpath('//xmlns:trkpt')の代わりにdoc.xpath('//trkpt')

Railsモデルのメソッドは次のとおりです。

def self.parse_gpx(filename)
  file = File.open(filename)
  doc = Nokogiri::XML(file)
  trackpoints = doc.xpath('//xmlns:trkpt')
  route = Array.new
  trackpoints.each do |trkpt|
    lat = trkpt.xpath('@lat').to_s.to_f
    lon = trkpt.xpath('@lon').to_s.to_f
    ele = trkpt.text.strip.to_f
    route << {lat: lat, lon: lon, ele: ele}
  end
  route
end

これは私の出力です:

1.9.3p194 :329 > Route::parse_gpx("gpx/short.gpx")
 => [{:lat=>54.066335, :lon=>-2.005, :ele=>171.1}, {:lat=>54.06634, :lon=>-2.005, :ele=>172.8}, {:lat=>54.066338, :lon=>-2.004997, :ele=>172.0}]
于 2012-11-23T23:56:37.237 に答える