【问题标题】:Why etree.find doesn't find the element for the provided example为什么 etree.find 没有找到所提供示例的元素
【发布时间】:2015-01-04 09:37:52
【问题描述】:

假设它有这个:

xml_as_str = '''
<v1:Header>
    <v2:Person>Foo Bar</v2:Person>
    <v2:Email>foo@bar.com</v2:Email>
</v1:Header>
'''

from lxml import etree
tree = etree.fromstring(xml_as_str, etree.XMLParser(recover=True))

它如何获得某个标签的值,例如 v2:Person 的“Foo Bar”?

我试过了:

 >> tree.find('.//v2:Person')
 >> tree.find('.//{Person}v2')

为了得到元素然后.text,但是.find没有找到元素,为什么?

【问题讨论】:

    标签: python xml xml-parsing lxml


    【解决方案1】:

    使用local-name() xpath 函数:

    >>> xml_as_str = '''
    ... <v1:Header>
    ...     <v2:Person>Foo Bar</v2:Person>
    ...     <v2:Email>foo@bar.com</v2:Email>
    ... </v1:Header>
    ... '''
    >>>
    >>> from lxml import etree
    >>> tree = etree.fromstring(xml_as_str, etree.XMLParser(recover=True))
    >>> tree.xpath('//*[local-name()="v2:Person"]/text()')[0]
    'Foo Bar'
    

    【讨论】:

    • 谢谢@falsetru,这行得通!但是为什么.find 在这种情况下不起作用?
    • @trinchet, find 不支持所有的 xpath 表达式。
    【解决方案2】:

    你也可以使用 BeautifulSoup。

    In [1]: from bs4 import BeautifulSoup
    
    In [2]: xml_as_str = '''
       ...: <v1:Header>
       ...:     <v2:Person>Foo Bar</v2:Person>
       ...:     <v2:Email>foo@bar.com</v2:Email>
       ...: </v1:Header>
       ...: '''
    In [9]: soup = BeautifulSoup(xml_as_str, 'lxml')
    In [15]: for i in soup.find_all('v1:header'):
        ...:     for j in soup.find_all('v2:person'):
        ...:         print(j.text)
        ...:         
    Foo Bar
    
    In [16]:
    

    通过列表理解。

    In [17]: [j.text for i in soup.find_all('v1:header') for j in soup.find_all('v2:person')][0]
    Out[17]: 'Foo Bar'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多