【问题标题】:Find element neighbor查找元素邻居
【发布时间】:2014-02-05 22:06:57
【问题描述】:

我有以下两种格式的文档:

<p><b>Referral Description:</b></p>
<p>
 This is the body of the referral's detailed description. 
 I want to get this text out of the document.
</p>

<table>
  <tr>
    <td><b>FieldName:</b></td>
    <td>field value</td>
  </tr>
  <tr>
    <td><b>Field2Name:</b></td>
    <td>field value</td>
  </tr>
  <tr>
    <td><b>Field3Name:</b></td>
    <td>field value</td>
  </tr>
</table>

在这两种情况下,您都可以看到我需要一个位于未命名元素中的值,并且它的相邻邻居是具有 &lt;b&gt;FieldName:&lt;/b&gt; 主体的匹配标签。

我的问题是,如何使用邻居标签来获取我需要的值?我可以用

定位邻居
doc.xpath('//p/b[content(text(), "Referral Description:")]')

但我该如何接受并说“把你的邻居给我”?

【问题讨论】:

    标签: html ruby html-parsing nokogiri


    【解决方案1】:

    我会使用Axis - following-sibling::

    require 'nokogiri'
    
    doc = Nokogiri::HTML.parse <<-html
    <p><b>Referral Description:</b></p>
    <p>
     This is the body of the referral's detailed description. 
     I want to get this text out of the document.
    </p>
    html
    
    node = doc.xpath('//p[./b[contains(text(), "Referral Description:")]]/following-sibling::p')
    puts node.text
    # >> 
    # >>  This is the body of the referral's detailed description. 
    # >>  I want to get this text out of the document.
    

    或者,使用通配符*

    require 'nokogiri'
    
    doc = Nokogiri::HTML.parse <<-html
    <p><b>Referral Description:</b></p>
    <p>
     This is the body of the referral's detailed description. 
     I want to get this text out of the document.
    </p>
    html
    
    ["Referral Description:", "FieldName:", "Field1Name:"].map |header|
      doc.xpath("//*[./b[contains(text(), '#{header}')]]/following-sibling::*')
    end
    # >> 
    # >>  ["This is the body of the referral's detailed description.\nI want to get this text out of the document.", "field value", "field value"]
    

    HTML表格的第二部分:

    require 'nokogiri'
    
    doc = Nokogiri::HTML.parse <<-html
    <table>
      <tr>
        <td><b>FieldName:</b></td>
        <td>field value</td>
      </tr>
      <tr>
        <td><b>Field2Name:</b></td>
        <td>field value</td>
      </tr>
      <tr>
        <td><b>Field3Name:</b></td>
        <td>field value</td>
      </tr>
    </table>
    html
    
    field_ary = %w(FieldName Field2Name Field3Name)
    nodeset = field_ary.map{|n| doc.xpath("//td[./b[contains(.,'#{n}')]]/following-sibling::*")}
    nodeset.map{|n| n.text }
    # => ["field value", "field value", "field value"]
    

    或(另一种方法)

    nodeset = field_ary.map{|n| doc.xpath("//*[./b[contains(.,'#{n}')]]/following-sibling::*")}
    nodeset.map{|n| n.text }
    # => ["field value", "field value", "field value"]
    

    【讨论】:

    • 我没有安装 Nokogiri,如果following-sibling::* 对 OP 的两个示例都有效,你能试试吗?
    • 我的意思是,如果有一个通配符可以让您在两个示例中使用相同的语句,而不指定 ::p::td
    • 是的,这就是我的意思,+1。
    • @MichaelKohl 有没有办法在 xpath 的开头也使用通配符,例如//*[./b[contains(...)] 或类似的?在这种情况下,通配符的作用会更大。
    【解决方案2】:

    在css中,下一个相邻兄弟选择器是+

    doc.at('p:has(b[text()="Referral Description:"]) + p').text
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-29
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多