2014-11-15 37 views
3

標籤我試圖使用LXML獲得的標籤數組作爲LXML找到正則表達式

<TEXT1>TEXT</TEXT1> 

<TEXT2>TEXT</TEXT2> 

<TEXT3>TEXT</TEXT3> 

我嘗試使用

xml_file.findall("TEXT*") 

被格式化,但這個搜索文字星號。

我也嘗試使用ETXPath但它似乎無法正常工作。 是否有任何API函數可以使用,因爲假設 TEXT被整數追加不是最漂亮的解決方案。

回答

7

是的,你可以使用regular expressions in lxml xpath

下面是一個例子:

results = root.xpath(
    "//*[re:test(local-name(), '^TEXT.*')]", 
    namespaces={'re': "http://exslt.org/regular-expressions"}) 

當然,在你提到你並不真的需要一個正則表達式的例子。您可以使用starts-with() XPath函數:

results = root.xpath("//*[starts-with(local-name(), 'TEXT')]") 

完整的程序:

from lxml import etree 

root = etree.XML(''' 
    <root> 
     <TEXT1>one</TEXT1> 
     <TEXT2>two</TEXT2> 
     <TEXT3>three</TEXT3> 
     <x-TEXT4>but never four</x-TEXT4> 
    </root>''') 

result1 = root.xpath(
    "//*[re:test(local-name(), '^TEXT.*')]", 
    namespaces={'re': "http://exslt.org/regular-expressions"}) 

result2 = root.xpath("//*[starts-with(local-name(), 'TEXT')]") 

assert(result1 == result2) 

for result in result1: 
    print result.text, result.tag 

解決了新的要求,考慮這個XML:

<root> 
    <tag> 
     <TEXT1>one</TEXT1> 
     <TEXT2>two</TEXT2> 
     <TEXT3>three</TEXT3> 
    </tag> 
    <other_tag> 
     <TEXT1>do not want to found one</TEXT1> 
     <TEXT2>do not want to found two</TEXT2> 
     <TEXT3>do not want to found three</TEXT3> 
    </other_tag> 
</root> 

如果想找到所有TEXT元素是<tag>元素的直接子元素耳鼻喉科:

result = root.xpath("//tag/*[starts-with(local-name(), 'TEXT')]") 
assert(' '.join(e.text for e in result) == 'one two three') 

或者,如果一個人想所有TEXT元素僅是第一tag元素的直接孩子:

result = root.xpath("//tag[1]/*[starts-with(local-name(), 'TEXT')]") 
assert(' '.join(e.text for e in result) == 'one two three') 

或者,如果一個人想發現只有每個第一TEXT元素tag元件:

result = root.xpath("//tag/*[starts-with(local-name(), 'TEXT')][1]") 
assert(' '.join(e.text for e in result) == 'one') 

Resorources:http://www.w3schools.com/xpath/ http://lxml.de/xpathxslt:

+1

我在開發答案使用這些資源。 html。你也可能會發現它們很有用。 –

1

這裏有一個想法:

import lxml.etree 

doc = lxml.etree.parse('test.xml') 
elements = [x for x in doc.xpath('//*') if x.tag.startswith('TEXT')]