【问题标题】:Parsing sub nodes with Nokogiri使用 Nokogiri 解析子节点
【发布时间】:2015-10-31 07:43:05
【问题描述】:

我正在尝试使用 Nokogiri 的 XPath 解析这个 XML 结构。

<root>
  <resource id='1' name='name1>
     <prices>
         <price datefrom='2015-01-01' dateto='2015-05-31' price='3000' currency='EUR'></price>
         <price datefrom='2015-06-01' dateto='2015-12-31' price='4000' currency='EUR' ></price>                        
     </prices>
  </resource>
  <!-- many more resource nodes -->
<root>

我正在迭代每个资源,对于每个资源,我需要获取它的 &lt;prices&gt; 元素:

resourcesParsed = Nokogiri::XML(resourcesXML)
    resources = resourcesParsed.xpath("//resource")      
      for resource in resources do
        id = resource["id"]
        # insert in resources tables
        # parsing resource prices
        getPrices(resource)
      end
    ...

def getPrices(resource)
  prices = resource.xpath("//price") 
  @logger.debug "prices=" + prices.to_s
  # do whatever
end 

由于某种原因,当我尝试解析 //price 时,它不仅获得了资源中的 &lt;price&gt; 节点,而且还获得了整个 XML 文档中的所有 &lt;prices&gt; 节点。

如何只解析资源的&lt;price&gt; 节点?

【问题讨论】:

  • 作为编码风格建议,不要使用for resource in resources do。而是使用each 进行迭代。它是更干净和惯用的 Ruby。此外,我们不使用 camelCase 来表示变量或方法名;相反,我们使用snake_case。它的 AMatterOfReadability。

标签: ruby nokogiri


【解决方案1】:

我明白了。

代替:

prices = resource.xpath("//price") 

我应该搜索:

prices = resource.xpath(".//price") 

指向当前节点。

【讨论】:

    【解决方案2】:

    我会这样写代码:

    resources = doc.search('resource').map{ |resource|
      [
        resource['id'],
        resource.search('price').map{ |price|
          {
            price:    price['price'],
            datefrom: price['datefrom'],
            dateto:   price['dateto'],
            currency: price['currency']
          }
        }
      ]
    }
    

    此时resources是一个哈希数组,每个子数组是一个resource及其嵌入的价格:

    # => [["1",
    #      [{:price=>"3000",
    #        :datefrom=>"2015-01-01",
    #        :dateto=>"2015-05-31",
    #        :currency=>"EUR"},
    #       {:price=>"4000",
    #        :datefrom=>"2015-06-01",
    #        :dateto=>"2015-12-31",
    #        :currency=>"EUR"}]]]
    

    如果它是子数组的散列,它会更容易重用于查找或进一步处理,其中每个子数组都是一个price

    resources.to_h
    # => {"1"=>
    #      [{:price=>"3000",
    #        :datefrom=>"2015-01-01",
    #        :dateto=>"2015-05-31",
    #        :currency=>"EUR"},
    #       {:price=>"4000",
    #        :datefrom=>"2015-06-01",
    #        :dateto=>"2015-12-31",
    #        :currency=>"EUR"}]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-03
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-18
      相关资源
      最近更新 更多