xpath指定多列的方法

How to specify multiple column by xpath

我想从 HTML 中获取多个 table 数据,如下所示:

html = <<EOF
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
</table>
EOF

我想从中获取两个数据:

noko = Nokogiri::HTML(html)
noko.xpath("//tr[1]/td[2]").text #=> "2"
noko.xpath("//tr[1]/td[3]").text #=> "3"

我对这段代码的期望是“23”,但return是“123”。 我怎样才能使用 xpath 只得到“23”?

noko.xpath("//tr[1]/td[2 and 3]").text

有多种方法可以解决这个问题。一个是:

require 'nokogiri'

html = <<EOF
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
</table>
EOF

noko = Nokogiri::HTML(html)
p noko.xpath("//tr[1]/td[position()= 2 or position() = 3]").map(&:text).join 
# => 23
# another way
p noko.xpath("//tr[1]/td[2]", "//tr[1]/td[3]").map(&:text).join
# => 23

如果您不依赖 XPath,可以使用 CSS:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOF)
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
</table>
EOF

td_data = doc.search('tr').map { |tr|
  tr.search('td:nth-child(2), td:nth-child(3)').map(&:text)
}
td_data # => [["2", "3"], ["5", "6"]]

或者对于较旧的、不太兼容的浏览器:

td_data = doc.search('tr').map { |tr|
  tr.search('td:first-child + td, td:first-child + td + td').map(&:text)
}
td_data # => [["2", "3"], ["5", "6"]]

如果您需要返回的值是 "23" and/or "56" 使用:

td_data.map(&:join) # => ["23", "56"]

尽管我不明白为什么这会过于有用。

怎么样:

doc.search('tr[1] td:gt(1)').text
#=> "23"

使用position()使用xpath获取几个不同位置索引的元素,例如:

//tr[1]/td[position()=2 or position()=3]

您还可以使用 xpath 联合运算符 (|) 组合多个 xpath 表达式,如下所示:

//tr[1]/td[2] | //tr[1]/td[3]

我更喜欢前一种方式,但联合可能是不同情况下唯一的选择,所以值得一提。