簡體   English   中英

如何使用Ruby和REXML獲取XML頁面的子節點

[英]How to get child node of an XML page using Ruby and REXML

我正在使用Ruby 1.9.3版。 這是我想從中獲取信息的實際XML頁面的簡單版本。 我需要從需要登錄憑據的安全網站訪問它。 我無法使用Nokogiri,因為我無法使用它登錄該網站。

<root>
  <person>
    <name>Jack</name>
    <age>10</age>
  </person>
  <person>
    <name>Jones</name>
  </person>
  <person>
    <name>Jon</name>
    <age>16</age>
  </person>
</root>

如您所見,有時標記age不會出現。 結合使用REXML和Ruby,我使用以下代碼:

agent = Mechanize.new
xml = agent.get("https://securewebsite.com/page.xml")
document = REXML::Document.new(xml.body)

name = XPath.match(document, "//person/name").map {|x| x.text} 
# => ["Jack", "Jones", "Jon"]

age =  XPath.match(document, "//person/age").map {|x| x.text} 
# => ["10", "16"]

問題是我無法將age與正確的name相關聯,因為索引現在不正常了。 例如,在索引1處,名稱[1]是Jones,而age [1]是16。但這不是正確的,因為Jones的person標簽沒有年齡標簽。

有什么方法可以獲取age數組來輸出: # => ["10", nil ,"16"]以便可以將正確的名稱與其相應的年齡相關聯?

或者,還有更好的方法? 讓我知道是否需要進一步說明。

問題在於我們將年齡和姓名視為完全獨立的信息集合。 我們需要做的是從個人那里收集信息。

xml = "<your xml here />"
doc = Nokogiri::XML(xml)
persons = doc.xpath("//person")
persons_data = persons.map {|person| 
  {
    name: person.xpath("./name").text,
    age: person.xpath("./age").text
  }
}

這將獲取人員節點,然后從其獲取相關信息以給出結果:

puts persons_data.inspect #=> [
                                {:name=>"Jack", :age=>"10"}, 
                                {:name=>"Jones", :age=>""}, 
                                {:name=>"Jon", :age=>"16"}
                              ]

因此,要獲取第一人稱呼的姓名和年齡

persons_data[0]["name"] #=> "Jack"
persons_data[0]["age"]  #=> "10"

我會做這樣的事情:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<root>
  <person>
    <name>Jack</name>
    <age>10</age>
  </person>
  <person>
    <name>Jones</name>
  </person>
  <person>
    <name>Jon</name>
    <age>16</age>
  </person>
</root>
EOT

people = doc.search('person').each_with_object({}){ |person, h|
  age = person.at('age')
  h[person.at('name').text] = age ? age.text : nil
}

people # => {"Jack"=>"10", "Jones"=>nil, "Jon"=>"16"}

在這一點上,如果我只想歲,我會使用values

people.values # => ["10", nil, "16"]

那么,獲取一個人的年齡很簡單:

people['Jon'] # => "16"
people['Jack'] # => "10"

我在使用.to_h方法時收到此錯誤:``在':中阻止:未定義的方法to_h'

我的錯。 to_h不在較舊的to_h中,但是由於我如何生成返回的哈希,因此不需要它。 我調整了上面的代碼,該代碼將在實現each_with_object任何Ruby中each_with_object

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM