XML 扫描价值

XML scanning for value

我有一个 XML 具有以下结构,我从 API -

<entry>
    <id>2397</id>
    <title>action_alert</title>
    <tes:actions>
        <tes:name>action_alert</tes:name>
        <tes:type>2</tes:type>
    </tes:actions>
</entry>

我正在通过执行以下操作来扫描 ID -

sourceobject = etree.parse(urllib2.urlopen(fullsourceurl))
source_id = sourceobject.xpath('//id/text()')[0]

我也想得到tes:type

source_type = sourceobject.xpath('//tes:actions/tes:type/text()')[0]

无效。它给出了以下错误 -

lxml.etree.XPathEvalError: 未定义的命名空间前缀

如何让它忽略命名空间?

或者,我知道这个命名空间 -

<tes:action xmlns:tes="http://www.blah.com/client/servlet">

我不太确定命名空间的事情,但我认为使用它会更容易 beautifulsoup: (text为正文)

from bs4 import BeautifulSoup

soup = BeautifulSoup(text)

ids = []
get_ids = soup.find_all("id")
for tag in get_ids:
    ids.append(tag.text)

#ids is now ['2397']

types = []
get_types = soup.find_all("tes:actions")
for child in get_types:
    type = child.find_all("tes:type")
    for tag in type:
        types.append(tag.text)

#types is now ['2']

访问命名空间中节点的正确方法是将前缀命名空间 URL 映射作为附加参数传递给 xpath() 方法,例如:

ns = {'tes' : 'http://www.blah.com/client/servlet'}
source_type = sourceobject.xpath('//tes:actions/tes:type/text()', namespaces=ns)

或者,另一种不太推荐的方法,通过使用 xpath 函数从字面上忽略命名空间 local-name() :

source_type = sourceobject.xpath('//*[local-name()="actions"]/*[local-name()="type"]/text()')[0]