2011-05-21 120 views
10

我试图使用Nokogiri来显示URL的结果。 (实质上是刮掉一个URL)。通过类属性的部分匹配获取所有元素

我有一些HTML它类似于:

<p class="mattFacer">Matty</p> 
<p class="mattSmith">Matthew</p> 
<p class="suzieSmith">Suzie</p> 

所以,我需要再找到所有与单词“亚光”开头的元素。我需要做的是保存元素的值和元素的名称,这样我可以参考它下一次..所以我需要捕获

"Matty" and "<p class='mattFacer'>" 
"Matthew" and "<p class='mattSmith'>" 

我还没有制定出如何捕捉元素HTML,但这里是我迄今为止的元素(它不工作!)

doc = Nokogiri::HTML(open(url)) 
tmp = "" 
doc.xpath("[class*=matt").each do |item| 
    tmp += item.text 
end 

@testy2 = tmp 
+0

好问题,+1。查看我的答案,获得完整,简短且易于使用的XPath表达式解决方案。 :) – 2011-05-21 23:26:22

+0

有人在这里看到铁轨? – Nakilon 2013-01-04 11:17:43

回答

15

这应该让你开始:

doc.xpath('//p[starts-with(@class, "matt")]').each do |el| 
    p [el.attributes['class'].value, el.children[0].text] 
end 
["mattFacer", "Matty"] 
["mattSmith", "Matthew"] 
+0

是的 - 这似乎是伎俩!谢谢!有没有一种方法可以搜索类名的任何部分?所以如果它是

我将如何搜索?基本上它可以是任何东西,但我想抓住亚光部分!感谢您在这里的帮助:) – 2011-05-21 16:49:03

+5

XPath有许多功能,例如'starts-with',例如。 'contains'和'substring'。 http://www.w3.org/TR/xpath/#corelib – 2011-05-21 17:04:35

+0

优秀 - 谢谢!我用contains()来匹配 - 完美! – 2011-05-21 17:14:48

2

使用

/*/p[starts-with(@class, 'matt')] | /*/p[starts-with(@class, 'matt')]/text() 

这将选择任何p元素是XML文档的顶部元素的子元素和其class属性与"matt"和任何此类p任何文本子节点开始的值元件。

当针对这个XML文档(在没有提供!)评价:

<html> 
    <p class="mattFacer">Matty</p> 
    <p class="mattSmith">Matthew</p> 
    <p class="suzieSmith">Suzie</p> 
</html> 

以下节点被选择(每一个单独的行),并且可以通过位置进行访问:

<p class="mattFacer">Matty</p> 
Matty 
<p class="mattSmith">Matthew</p> 
Matthew 

以下是快速XSLT验证

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:for-each select= 
    "/*/p[starts-with(@class, 'matt')] 
    | 
    /*/p[starts-with(@class, 'matt')]/text() 
    "> 
    <xsl:copy-of select="."/> 
    <xsl:text>&#xA;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

此转换的结果,当在同一个XML文档(以上)应用是预期的,选择的节点的正确顺序

<p class="mattFacer">Matty</p> 
Matty 
<p class="mattSmith">Matthew</p> 
Matthew 
0

接受的答案是伟大的,但另一种方法是是使用Nikkou,它可以让你通过正则表达式匹配(无需熟悉XPATH功能):

doc.attr_matches('class', /^matt/).collect do |item| 
    [item.attributes['class'].value, item.text] 
end 
0
doc = Nokogiri::HTML(open(url)) 
tmp = "" 
items = doc.css("p[class*=matt]").map(&:text).join 
+1

错字'css(“p [class * = matt]”)' – hlcs 2016-11-06 23:44:03