2010-02-17 51 views
16

我使用引入nokogiri選擇「關鍵字」屬性,像這樣:如何創建nokogiri不區分大小寫的Xpath選擇器?

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中的「匹配」概念有什麼關係(因此可用於解決此問題)?

非常感謝。

+1

+1 - 很好的問題。歡迎來到SO :) – 2010-02-17 14:36:31

回答

9

裹的可讀性:

puts page.parser.xpath(" 
    //meta[ 
    translate(
     @name, 
     'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
     'abcdefghijklmnopqrstuvwxyz' 
    ) = 'keywords' 
    ] 
").to_html 

有XPath 1.0中沒有「小寫」的功能,所以你必須使用translate()爲這種事情。根據需要添加重音字母。

+0

非常感謝Tomalak。這個解決方案對我來說很好。 – Rick 2010-02-22 03:48:24

+0

僅供參考,VTD-XML的xpath 1.0實際上實現了upperCase和lowerCase作爲某種中間步驟到2.0 – 2010-02-24 08:12:25

19

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的節點集。所以打電話給to_s就可以了。 (或者,您可以使用node.value。)

與使用必須指定每個字符的XPath translate不同,它適用於所有Ruby處理的字符和字符編碼。另外,如果您有興趣做除XPath 1.0不支持的不區分大小寫匹配之外的其他任何事情,則此時只是Ruby。所以這是一個很好的起點。

+0

非常優雅的解決方案! – Severin 2014-12-10 10:37:31

相關問題