XPath:如何从这个和下一个标签获取文本?

时间:2011-08-01 18:58:24

标签: xpath

我有这样的HTML:

<h1>Hello1</h1>
<p>World1</p>
<h1>Hello2</h1>
<p>World2</p>
<h1>Hello2</h1>
<p>World2</p>

所以我需要一次性使用World1获得Hello1,使用World2等获取Hello2等

更新:我使用Ruby Mechanize库

2 个答案:

答案 0 :(得分:3)

Ruby库“Mechanize”使用Nokogiri解析库,因此您可以直接调用Nokogiri。一个可能的解决方案可能看起来像这样:

require 'mechanize'
require 'pp'

html = "<h1>Hello1</h1>
<p>World1</p>
<h1>Hello2</h1>
<p>World2</p>
<h1>Hello2</h1>
<p>World2</p>"

results = []

Nokogiri::HTML(html).xpath("//h1").each do |header|
  p   = header.xpath("following-sibling::p[1]").text
  results << [header.text, p]
end

pp results

修改 该示例使用Mechanize v2.0.1进行测试,该版本使用Nokogiri~v1.4。我也没有问题直接针对Nokogiri v1.5.0测试。

编辑#2: 此示例回答了原始解决方案的后续问题:

require 'nokogiri'
require 'pp'

html = <<HTML
<h1>
<p>
<font size="4">
<b>abide by (something)</b>
</font>
</p>
</h1>
<p>
<font size="3">- to follow the rules of something</font>
</p>
The cleaning staff must abide by the rules of the school.
<br>
<h1>
<p>
<font size="4">
<b>able to breathe easily again</b>
</font>
</p>
</h1>
<p>
My friend was able to breathe easily again when his company did not go bankrupt.
<br>
HTML

doc = Nokogiri::HTML(html)

results = []

Nokogiri::HTML(html).xpath("//h1").each do |header|
  h1   = header.xpath("following-sibling::p/font/b").text
  results << h1
end

pp results
嵌套元素的

H1标记无效,因此Nokogiri会在解析过程中纠正错误。获取以前嵌套元素的过程与原始解决方案非常相似。

答案 1 :(得分:1)

注意:我对此请求的XPath部分进行了釉面处理。这个答案适用于XSLT样式表。

扩展XML示例以为其提供根元素:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <h1>Hello1</h1>
    <p>World1</p>
    <h1>Hello2</h1>
    <p>World2</p>
    <h1>Hello3</h1>
    <p>World3</p>
</root>

您可以使用for-each循环和“follow-sibling”来获取具有以下内容的元素:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output encoding="UTF-8" method="text"/>

    <xsl:template match="/">

        <!-- start lookint for <h1> nodes -->
        <xsl:for-each select="/root/h1">

            <!-- output the h1 text -->
            <xsl:value-of select="."/>

            <!-- print a dash for spacing -->
            <xsl:text> - </xsl:text>

            <!-- select the next <p> node -->
            <xsl:value-of select="following-sibling::p[1]"/>

            <!-- print a new line -->
            <xsl:text>&#10;</xsl:text>

        </xsl:for-each>

    </xsl:template>

</xsl:stylesheet>

输出如下:

Hello1 - World1
Hello2 - World2
Hello3 - World3