Ruby rails - 在不知道长度的情况下解析xml条目列表

时间:2012-04-18 04:37:12

标签: ruby xml ruby-on-rails-3

我正在使用XmlSimple,我遇到的问题是解析条目列表,确定具有类似xml标记的条目数。

<ItemList>
   <Item>
      <ItemId>123</ItemId>
      <ItemName>abc</ItemName>
      <ItemType>xyz</ItemType>
      <Status>ok</Status>
   </Item>
</ItemList>

上面被解析为 -

"ItemList"=> { 
    "Item"=>{ "ItemId"=>"123", 
              "ItemName"=>"abc", 
              "ItemType"=>"xyz", 
              "Status"=>"ok"
             }
},

我将其作为 - ['ItemList']['Item']['ItemId']访问,任何地方都没有任何索引编号。

但是如果ItemList有超过1个条目,那么它会弄乱我的应用程序。

<ItemList>
   <Item>
      <ItemId>123</ItemId>
      <ItemName>abc</ItemName>
      <ItemType>xyz</ItemType>
      <Status>bad</Status>
   </Item>
   <Item>
      <ItemId>456</ItemId>
      <ItemName>fgh</ItemName>
      <ItemType>nbv</ItemType>
      <Status>bad</Status>
   </Item>
</ItemList>

上面被解析为 -

"ItemList"=> { 
    "Item"=>{ "ItemId"=>"123", 
              "ItemName"=>"abc", 
              "ItemType"=>"xyz", 
              "Status"=>"bad"
             },
    "Item"=>{ "ItemId"=>"456", 
              "ItemName"=>"fgh", 
              "ItemType"=>"nbv", 
              "Status"=>"bad"
             }
},

我可以将其作为 - ['ItemList']['Item'][0]['ItemId']['ItemList']['Item'][1]['ItemId']进行访问。手动提供索引号。 但由于我不知道列表中有多少项目,我无法在实际应用程序中提供索引编号,因此xml可能没有条目或者可能有数百条。 考虑使用Nokogiri,但它具有相同的解析行为。 我该如何处理?

3 个答案:

答案 0 :(得分:1)

使用xml-simple gem

对数据进行示例处理
1.9.2p290 :013 > items = "<ItemList> <Item> <ItemId>123</ItemId> <ItemName>abc</ItemName> <ItemType>xyz</ItemType> <Status>bad</Status> </Item> <Item> <ItemId>456</ItemId> <ItemName>fgh</ItemName> <ItemType>nbv</ItemType> <Status>bad</Status> </Item> </ItemList>"
     => "<ItemList> <Item> <ItemId>123</ItemId> <ItemName>abc</ItemName> <ItemType>xyz</ItemType> <Status>bad</Status> </Item> <Item> <ItemId>456</ItemId> <ItemName>fgh</ItemName> <ItemType>nbv</ItemType> <Status>bad</Status> </Item> </ItemList>" 

1.9.2p290 :014 > parsed_items = XmlSimple.xml_in(items, { 'KeyAttr' => 'name' })
     => {"Item"=>[{"ItemId"=>["123"], "ItemName"=>["abc"], "ItemType"=>["xyz"], "Status"=>["bad"]}, {"ItemId"=>["456"], "ItemName"=>["fgh"], "ItemType"=>["nbv"], "Status"=>["bad"]}]} 

1.9.2p290 :015 > parsed_items.class
     => Hash 

1.9.2p290 :016 > parsed_items["Item"].class
     => Array 

1.9.2p290 :017 > parsed_items["Item"].length
     => 2 

因此,您的Item将是一个数组,您可以对其应用length方法。通过上面的示例,您始终可以parsed_items["Item"].length

答案 1 :(得分:0)

如果“结果”是您解析XML文档的结果,那么您可以测试

result['ItemList']['Item']

检查它是否是数组(或可枚举)。如果是,那么有超过1个项目,你必须枚举这些项目。

或者,您可以这样做(假设ruby 1.9):

[*result['ItemList']['Item']].each do |item|
   ...
end

splat运算符是cool,当这样使用时,您可以透明地处理可能为nil,标量或集合的值。

答案 2 :(得分:0)

如果您使用的是Ruby 1.8+,我使用REXML可以轻松实现。请参阅访问元素部分:http://www.germane-software.com/software/rexml/docs/tutorial.html