【问题标题】:Python XML Parsing with Tag Specific Info带有标签特定信息的 Python XML 解析
【发布时间】:2014-12-26 05:15:09
【问题描述】:
我有一个结构如下的 XML 文件:
<?xml version="1.0">
<title>
<ch bk="Book1" num="1">
<ver num="1">ver1 content</ver>
<ver num="2">ver2 content</ver>
</ch>
<ch bk="Book1" num="2">
<ver num="1">ver1 content</ver>
<ver num="2">ver2 content</ver>
</ch>
<ch bk="Book2" num="1">
<ver num="1">ver1 content</ver>
<ver num="2">ver2 content</ver>
</ch>
</title>
有没有办法可以在 python 中访问特定 ch num and book 的单个 ver 内容? (例如 access ver num=2 of ch num=2 of bk=Book1)
我已经查看了一些解析 XML 的 xml 模块类,但是它们通过 tagName 进行,我看不到在哪里可以输入诸如 num、bk 和 ch 之类的信息。
非常感谢!
【问题讨论】:
标签:
python
xml
parsing
tree
【解决方案1】:
您可以使用精细的xpath 表达式访问元素:
XPath 解释
// 代表相对递归搜索
'//ch[@num="1"][@bk="Book1"]/ver[@num="1"]'
# ^ ^ ^ ^ ^
# ch node | | | |
# + attributes num = 1 | |
# + AND Book attribute = 1 | |
# ver node |
# + num attribut = 1
python 代码:
from lxml import etree
fp = open("/tmp/xml.xml")
tree = etree.parse(fp)
print(tree.xpath('//ch[@num="1"][@bk="Book1"]/ver[@num="1"]/text()')[0])
【解决方案2】:
使用 Python 标准库的xml.etree.ElementTree 的简单方法:
import xml.etree.ElementTree as ET
tree = ET.parse('yourfile.xml')
def locate(chnum, bk, vernum):
for ch in tree.findall('ch'):
if ch.get('num') != chnum: continue
if ch.get('bk') != bk: continue
for ver in ch.findall('ver'):
if ver.get('num') != vernum: continue
return ver.text
return None # no such chapter/book/version combo found
【解决方案3】:
是的,你可以使用 xpath 来获取目标标签。
>>> from lxml import etree
>>> fp = open("test.html")
>>> tree = etree.parse(fp)
>>> r = tree.xpath('//ch[@num=2][@bk="Book1"]/ver/text()')
>>> r
['ver1 content', 'ver2 content']
【解决方案4】:
这样,您可以将ver 作为元素访问。
import xml.etree.ElementTree as etree
tree = etree.ElementTree(file='input.xml')
#inputs
num = '1'
bk = 'Book2'
#list comprehension (assume num and bk is unique for ch)
vers = [ch.findall('ver') \
for ch in tree.findall('ch') \
if ch.attrib['num'] == num and ch.attrib['bk'] == bk][0]
#loop results
for ver in vers:
print 'num={0} text={1}'.format(ver.attrib['num'], ver.text)