【问题标题】:Map two Nokogiri objects映射两个 Nokogiri 对象
【发布时间】:2015-05-07 14:50:29
【问题描述】:

一个简单的问题:

<table>
  <tr>
    <th>foo</th>
    <td><p>bar</p></td>
  </tr>
</table>

  details  = doc.css('table > tr > th')
  details2 = doc.css('table > tr > td > p')

  details  = details.map { |n| { name: n.text }}
  details2 = details2.map { |n| { value: n.text }}

如何将这些 Nokogiri 对象合并到一个 map 语句中?

输出:

{:name=>"abc"}
{:name=>"ghj"}
{:name=>"lmn"}
{:value=>"123"}
{:value=>"456"}
{:value=>"789"}

我需要这样的东西:

{:name=>"abc", :value=>"123"}

我尝试过这样的事情:

details = details.map { |n| { name: n.text, value: n.css('table > tr > td > p').map { |x| {value: x} }}}
details = details.map { |n| {name: n.text, value: n.css('table > tr > td').attr('p').to_s} }

【问题讨论】:

  • 欢迎使用 Stack Overflow。您需要提供一个最小的 HTML 示例来显示您正在谈论的内容。要求我们拼凑一些东西只会减慢我们的速度,并增加您获得对您的用例不起作用的东西的机会。

标签: ruby nokogiri mechanize


【解决方案1】:

CSS 支持多个选择器,Nokogiri 对 CSS 的使用遵循以下原则:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<html>
  <body>
    <table>
      <tr>
        <th>foo</th>
        <td><p>bar</p></td>
      </tr>
    </table>
  </body>
</html>
EOT

text = doc.search('table tr th, table tr td p').map(&:text)
text # => ["foo", "bar"]

或者更干净一点:

rows = doc.search('table tr')
text = rows.search('th, td p').map(&:text)
text # => ["foo", "bar"]

请注意,多个选择器按顺序工作。换句话说,他们找到第一个选择器然后是第二个,依此类推,所以如果您需要知道文档中发生的实际顺序,您将不得不使用单独的搜索或查看实际节点来确定它们在DOM。

还请注意,我使用的是通用 search,而不是更具体的 css。在使用 CSS 或 XPath 时,Nokogiri 足够聪明,大多数时候都会做正确的事情,因此使用 searchat 会更方便。

【讨论】:

    【解决方案2】:

    假设,数组包含有效/相同顺序的对象:

    details.zip(details2).map { |e| e.inject &:merge }
    

    【讨论】:

      【解决方案3】:

      最简单的方法:

      details  = doc.css('table > tr > th')
      details2 = doc.css('table > tr > td > p')
      
      details.map!.with_index { |d, i| {name: d.text, value: details2[i].text } }
      

      details 看起来像 [{name: 'asd', value: '123'}, {name: 'qwe', value: '234'}]

      【讨论】:

      • 早上好,感谢大家帮助尽快完成这个问题。但我只能接受一个答案,这是最接近我的问题的答案。祝你有美好的一天!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      • 2013-01-19
      • 2014-08-03
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      相关资源
      最近更新 更多