我正在使用nokogiri来选择'keywords'属性,如下所示:
puts page.parser.xpath("//meta[@name='keywords']").to_html
我正在使用的其中一个页面的关键字标签带有大写字母“K”,这促使我使查询不区分大小写。
<meta name="keywords"> AND <meta name="Keywords">
所以,我的问题是:使nokogiri选择案例不敏感的最佳方法是什么?
编辑以下Tomalak的建议适用于此特定问题。我也想用这个例子来帮助更好地理解nokogiri,并且有一些我想知道并且没有成功搜索的问题。例如,正则表达式'伪类'Nokogiri Docs是否适用于这样的问题?
我也很好奇nokogiri中的匹配?()方法。我无法找到有关该方法的任何说明。它是否与XPath 2.0中的“匹配”概念有关(因此可以用它来解决这个问题)?
非常感谢。
答案 0 :(得分:21)
Nokogiri允许自定义XPath功能。您链接的nokogiri文档显示内联类定义,以便您仅使用一次。如果您有很多自定义函数,或者如果您经常使用不区分大小写的匹配,则可能需要在类中定义它。
class XpathFunctions
def case_insensitive_equals(node_set, str_to_match)
node_set.find_all {|node| node.to_s.downcase == str_to_match.to_s.downcase }
end
end
然后像任何其他XPath函数一样调用它,将类的实例作为第二个参数传递。
page.parser.xpath("//meta[case_insensitive_equals(@name,'keywords')]",
XpathFunctions.new).to_html
在您的Ruby方法中,node_set
将绑定到Nokogiri::XML::NodeSet
。在传入类似@name
的属性值的情况下,它将是具有单个Nokogiri::XML::Attr
的NodeSet。所以在它上面调用to_s
会给你它的价值。 (或者,您可以使用node.value
。)
与使用必须指定每个字符的XPath translate
不同,这适用于Ruby所使用的所有字符和字符编码。
另外,如果除了XPath 1.0不支持的不区分大小写的匹配之外你还想做其他的事情,那么它就是Ruby。所以这是一个很好的起点。
答案 1 :(得分:9)
包装易读:
puts page.parser.xpath("
//meta[
translate(
@name,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'
) = 'keywords'
]
").to_html
XPath 1.0中没有“小写”功能,所以你必须使用translate()
来做这种事情。根据需要添加重音字母。