2012-06-27 46 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