给定以下简单的 XML 数据:
<book>
<title>My First Book</title>
<abstract>
<para>First paragraph of the abstract</para>
<para>Second paragraph of the abstract</para>
</abstract>
<keywordSet>
<keyword>First keyword</keyword>
<keyword>Second keyword</keyword>
<keyword>Third keyword</keyword>
</keywordSet>
</book>
我如何遍历树,使用 lxml , 并获取“abstract”元素中的所有段落,以及“keywordSet”元素中的所有关键字?
下面的代码片段仅返回每个元素中的第一行文本:
from lxml import objectify
root = objectify.fromstring(xml_string) # xml_string contains the XML data above
print root.title # returns the book title
for line in root.abstract:
print line.para # returns only yhe first paragraph
for word in root.keywordSet:
print word.keyword # returns only the first keyword in the set
我试着关注 this example ,但上面的代码没有按预期工作。
换一种方式,更好的办法是将整个 XML 树读入 Python 字典,将每个元素作为键,将每个文本作为元素项。我发现使用 lxml objectify 可能会实现类似的功能,但我不知道如何实现它。
我在尝试用 Python 编写 XML 解析代码时发现的一个非常大的问题是,所提供的大多数“示例”都太简单而且完全是虚构的,没有多大帮助——否则它们恰恰相反, 使用过于复杂的自动生成的 XML 数据!
有人可以给我提示吗?
提前致谢!
编辑:发布这个问题后,我找到了一个简单的解决方案 here .
所以,我更新后的代码变成了:
from lxml import objectify
root = objectify.fromstring(xml_string) # xml_string contains the XML data above
print root.title # returns the book title
for para in root.abstract.iterchildren():
print para # now returns the text of all paragraphs
for keyword in root.keywordSet.iterchildren():
print keyword # now returns all keywords in the set
最佳答案
使用 XPath 非常简单:
from lxml import etree
tree = etree.parse('data.xml')
paragraphs = tree.xpath('/abstract/para/text()')
keywords = tree.xpath('/keywordSet/keyword/text()')
print paragraphs
print keywords
输出:
['First paragraph of the abstract', 'Second paragraph of the abstract']
['First keyword', 'Second keyword', 'Third keyword']
参见 the XPath Tutorial at W3Schools有关 XPath 语法的详细信息。
特别是上面表达式中使用的元素
- 用于选择根节点/直接子节点的
/
选择器。 - 用于选择各个元素的文本节点(“文本内容”)的
text()
运算符。
这是使用 Objectify API 实现的方法:
from lxml import objectify
root = objectify.fromstring(xml_string)
paras = [p.text for p in root.abstract.para]
keywords = [k.text for k in root.keywordSet.keyword]
print paras
print keywords
看起来root.abstract.para
实际上是shorthand对于 root.abstract.para[0]
。因此,您需要明确使用 element.iterchildren()
来访问所有子元素。
这不是真的,我们显然都误解了 Objectify API:
为了遍历 abstract
中的 para
,您需要遍历 root.abstract.para
,而不是 root.abstract
本身。这很奇怪,因为您直观地将 abstract
视为其节点的集合或容器,而该容器将由 Python 可迭代对象表示。但它实际上是表示序列的 .para
选择器。
关于python - 使用 Python lxml 处理嵌套元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26370098/