将XML集合(Pivotal Tracker故事)转换为Ruby散列/对象

我有一个XML格式的故事集。 我想解析文件并将每个故事作为散列或Ruby对象返回,以便我可以进一步操作Ruby脚本中的数据。

Nokogiri是否支持此function,或者是否有更好的工具/库可供使用?

XML文档具有以下结构,通过Pivotal Tracker的Web API返回:

   16376 feature http://www.pivotaltracker.com/story/show/16376 2 accepted A description Receivable index listing will allow selection viewing Tony Superman Tony Superman 2009/11/04 15:49:43 WST 2009/11/10 11:06:16 WST index ui,receivables   17427 feature http://www.pivotaltracker.com/story/show/17427 3 unscheduled  Validations in wizards based on direction Matthew McBoggle 2009/11/17 15:52:06 WST   17426 feature http://www.pivotaltracker.com/story/show/17426 2 unscheduled Manual payment needs a description field. Add description to manual payment Tony Superman 2009/11/17 15:10:41 WST payment process   17636 feature http://www.pivotaltracker.com/story/show/17636 3 unscheduled The SMS and email templates needs to be editable by merchants. Notifications are editable by the merchant Matthew McBoggle 2009/11/19 16:44:08 WST   

您可以利用ActiveSupport中的Hash扩展。 然后,您只需要在Nokogiri中解析文档,然后将节点集结果转换​​为哈希值。 此方法将保留属性类型(例如整数,日期,数组)。 (当然,如果您使用的是Rails,那么如果您在环境中使用Rails,则不必要求/包含活动支持或nokogiri。我在这里假设一个纯Ruby实现。)

 require 'rubygems' require 'nokogiri' require 'activesupport' include ActiveSupport::CoreExtensions::Hash doc = Nokogiri::XML.parse(File.read('yourdoc.xml')) my_hash = doc.search('//story').map{ |e| Hash.from_xml(e.to_xml)['story'] } 

这将生成一个哈希数组(每个故事节点一个),并根据属性保留键入,如下所示:

 my_hash.first['name'] => "Receivable index listing will allow selection viewing" my_hash.first['id'] => 16376 my_hash.first['id'].class => Fixnum my_hash.first['created_at'].class => Time 

一种单线解决方案将是这样的:

 # str_xml contains your xml xml = Nokogiri::XML.parse(str_xml) xml.search('//story').to_a.map{|node| node.children.inject({}){|a,c| a[c.name] = c.text if c.class == Nokogiri::XML::Element; a}} 

它返回一个哈希数组:

 >> xml.search('//story').to_a.map{|node| node.children.inject({}){|a,c| a[c.name] = c.text if c.class == Nokogiri::XML::Element; a}} => [{"id"=>"16376", "story_type"=>"feature", "url"=>"http://www.pivotaltracker.com/story/show/16376", "estimate"=>"2", "current_state"=>"accepted", "description"=>"A description", "name"=>"Receivable index listing will allow selection viewing", "requested_by"=>"Tony Superman", "owned_by"=>"Tony Superman", "created_at"=>"2009/11/04 15:49:43 WST", "accepted_at"=>"2009/11/10 11:06:16 WST", "labels"=>"index ui,receivables"}, {"id"=>"17427", "story_type"=>"feature", "url"=>"http://www.pivotaltracker.com/story/show/17427", "estimate"=>"3", "current_state"=>"unscheduled", "description"=>"", "name"=>"Validations in wizards based on direction", "requested_by"=>"Matthew McBoggle", "created_at"=>"2009/11/17 15:52:06 WST"}, {"id"=>"17426", "story_type"=>"feature", "url"=>"http://www.pivotaltracker.com/story/show/17426", "estimate"=>"2", "current_state"=>"unscheduled", "description"=>"Manual payment needs a description field.", "name"=>"Add description to manual payment", "requested_by"=>"Tony Superman", "created_at"=>"2009/11/17 15:10:41 WST", "labels"=>"payment process"}, {"id"=>"17636", "story_type"=>"feature", "url"=>"http://www.pivotaltracker.com/story/show/17636", "estimate"=>"3", "current_state"=>"unscheduled", "description"=>"The SMS and email templates needs to be editable by merchants.", "name"=>"Notifications are editable by the merchant", "requested_by"=>"Matthew McBoggle", "created_at"=>"2009/11/19 16:44:08 WST"}] 

但是,这会忽略所有XML属性,但是你还没有说过如何处理它们……;)

我想你可以坚持这个答案。

在这里可以找到更简单的一个。

这个xml是由Rails的ActiveRecord#to_xml方法生成的。 如果你使用rails,你应该能够使用Hash#from_xml来解析它。

也许Pivotal API的Ruby接口可以为您的任务提供更好的解决方案,请参阅https://github.com/jsmestad/pivotal-tracker …然后您可以像(来自文档)那样获取纯Ruby对象的故事:

 @a_project = PivotalTracker::Project.find(84739) @a_project.stories.all(:label => 'overdue', :story_type => ['bug', 'chore'])