2012-06-27 42 views
3

我試圖在XPath中使用lower-case函數來匹配國家或國家。 translate有點麻煩,所以使用小寫字母和我的Python版本2.6.6具有XPath 2.0支持我相信因爲小寫字母只在XPath 2.0中可用。如何使用lxml進行Python XPath不區分大小寫的搜索?

我如何在我的情況下使用小寫字母是我正在尋找的。希望這個例子是自我解釋的。我正在尋找['USA', 'US']作爲輸出(如果小寫評估的國家和國家相同,則可以一次性發送兩個國家)。

HTML:doc.htm

<html> 
    <table> 
     <tr> 
      <td> 
       Name of the Country : <span> USA </span> 
      </td> 
     </tr> 
     <tr> 
      <td> 
       Name of the country : <span> UK </span> 
      </td> 
     </tr> 
</table> 

的Python:

import lxml.html as lh 

doc = open('doc.htm', 'r') 
out = lh.parse(doc) 
doc.close() 

print out.xpath('//table/tr/td[text()[contains(. , "Country")]]/span/text()') 
# Prints : [' USA '] 
print out.xpath('//table/tr/td[text()[contains(. , "country")]]/span/text()') 
# Prints : [' UK '] 

print out.xpath('//table/tr/td[lower-case(text())[contains(. , "country")]]/span/text()') 
# Prints : [<Element td at 0x15db2710>] 

更新:

out.xpath('//table/tr/td[text()[contains(translate(., "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz") , "country")]]/span/text()') 

現在的追求離子仍然存在,我可以存儲爲一個全局變量「handlecase」翻譯部分,打印全局變量每當我做一個XPath?

事情是這樣工作的:

handlecase = """translate(., "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")""" 

out.xpath('//table/tr/td[text()[contains(%s , "country")]]/span/text()' % (handlecase)) 

但是爲了簡單性和可讀性的緣故,我想是這樣運行:

out.xpath('//table/tr/td[text()[contains(handlecase , "country")]]/span/text()') 
+3

從[lxml XPath文檔](http://lxml.de/xpathxslt.html):'lxml支持XPath 1.0';因此,使用lxml,您會被翻譯卡住。 –

+0

在這種情況下,我不確定爲什麼當我使用小寫字母時不會抱怨。在這個示例場景中,我對翻譯沒有太大的好運。謝謝! – ThinkCode

+0

[可能的重複](http://stackoverflow.com/questions/9804281/selectnodes-with-xpath-ignoring-cases/9805020#9805020) – JWiley

回答

2

使用

//td[translate(substring(text()[1], string-length(text()[1]) - 9), 
        'COUNTRY :', 
        'country' 
       ) 
     = 
     'country' 
     ] 
     /span/text() 

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:copy-of select= 
    "//td[translate(substring(text()[1], string-length(text()[1]) - 9), 
        'COUNTRY :', 
        'country' 
       ) 
     = 
     'country' 
     ] 
     /span/text() 
     "/> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉型施加在提供的XML文檔:

<html> 
     <table> 
      <tr> 
       <td> 
        Name of the Country : <span> USA </span> 
       </td> 
      </tr> 
      <tr> 
       <td> 
        Name of the country : <span> UK </span> 
       </td> 
      </tr> 
     </table> 
</html> 

XPath表達式求值和所選擇的兩個文本節點被複制到輸出:

USA UK 

說明

  1. 我們使用實現的XPath 2中的XPath 1.0表達式的特定變體。0標準功能ends-with($text, $s):這是:

.....

$s = substring($text, string-length($text) - string-length($s) +1) 

0.2。下一步是使用translate()函數將結尾的10個字符的長字符串轉換爲小寫字母,從而消除任何空格或任何「:」字符。

.3。如果結果是字符串(全部小寫)「country」,那麼我們選擇這個td的s = span孩子的子文本節點(本例中只有一個)。

5

我相信最簡單的事情得到你希望只是寫一個XPath擴展函數。

通過這樣做,你既可以寫一個lower-case()功能,或不區分大小寫的搜索。


你可以在這裏找到細節:http://lxml.de/extensions.html

+0

非常好的答案,但是如果沒有例子,你就贏不了。 – mykhal

+0

我並沒有試圖獲勝,只是爲了幫助。我想給出一個例子,但在我看來,鏈接有足夠的例子。 – stranac