【问题标题】:Convert XML collection (of Pivotal Tracker stories) to Ruby hash/object将 XML 集合(Pivotal Tracker 故事)转换为 Ruby 哈希/对象
【发布时间】:2010-12-19 08:21:31
【问题描述】:

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

Nokogiri 是否支持这一点,还是有更好的工具/库可以使用?

XML 文档具有以下结构,通过Pivotal Tracker's web API 返回:

<?xml version="1.0" encoding="UTF-8"?>
<stories type="array" count="145" total="145">
  <story>
    <id type="integer">16376</id>
    <story_type>feature</story_type>
    <url>http://www.pivotaltracker.com/story/show/16376</url>
    <estimate type="integer">2</estimate>
    <current_state>accepted</current_state>
    <description>A description</description>
    <name>Receivable index listing will allow selection viewing</name>
    <requested_by>Tony Superman</requested_by>
    <owned_by>Tony Superman</owned_by>
    <created_at type="datetime">2009/11/04 15:49:43 WST</created_at>
    <accepted_at type="datetime">2009/11/10 11:06:16 WST</accepted_at>
    <labels>index ui,receivables</labels>
  </story>
  <story>
    <id type="integer">17427</id>
    <story_type>feature</story_type>
    <url>http://www.pivotaltracker.com/story/show/17427</url>
    <estimate type="integer">3</estimate>
    <current_state>unscheduled</current_state>
    <description></description>
    <name>Validations in wizards based on direction</name>
    <requested_by>Matthew McBoggle</requested_by>
    <created_at type="datetime">2009/11/17 15:52:06 WST</created_at>
  </story>
  <story>
    <id type="integer">17426</id>
    <story_type>feature</story_type>
    <url>http://www.pivotaltracker.com/story/show/17426</url>
    <estimate type="integer">2</estimate>
    <current_state>unscheduled</current_state>
    <description>Manual payment needs a description field.</description>
    <name>Add description to manual payment</name>
    <requested_by>Tony Superman</requested_by>
    <created_at type="datetime">2009/11/17 15:10:41 WST</created_at>
    <labels>payment process</labels>
  </story>
  <story>
    <id type="integer">17636</id>
    <story_type>feature</story_type>
    <url>http://www.pivotaltracker.com/story/show/17636</url>
    <estimate type="integer">3</estimate>
    <current_state>unscheduled</current_state>
    <description>The SMS and email templates needs to be editable by merchants.</description>
    <name>Notifications are editable by the merchant</name>
    <requested_by>Matthew McBoggle</requested_by>
    <created_at type="datetime">2009/11/19 16:44:08 WST</created_at>
  </story>
</stories>

【问题讨论】:

    标签: xml ruby hash nokogiri pivotaltracker


    【解决方案1】:

    我觉得你可以坚持this的回答。

    可以找到更简单的here

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 在这种情况下我没有使用 Rails。
      【解决方案3】:

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

      # 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 属性,但是您还没有说明如何处理它们... ;)

      【讨论】:

        【解决方案4】:

        您可以利用 ActiveSupport 中的哈希扩展。然后您只需要在 Nokogiri 中解析您的文档,然后将节点集结果转换​​为哈希。此方法将保留属性类型(例如整数、日期、数组)。 (当然,如果您使用的是 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
        

        【讨论】:

          【解决方案5】:

          也许 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'])
          

          【讨论】:

            猜你喜欢
            • 2011-06-29
            • 2017-04-04
            • 1970-01-01
            • 1970-01-01
            • 2016-08-26
            • 2020-09-15
            • 2010-12-16
            • 2011-03-12
            • 2016-01-11
            相关资源
            最近更新 更多