给定如下 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 包含上面的 XML 数据 print root.title # 返回书名 for line in root.abstract: print line.para # 仅返回第一段 for word in root.keywordSet: print word.keyword # 仅返回集合中的第一个关键字
在不同的解决方法中,更好的方法是能够将整个 XML 树读入 Python 字典中,其中每个元素作为键,每个文本作为元素项。我发现可以使用 lxml objectify 实现类似的功能,但我无法弄清楚如何实现它。
我在尝试用 Python 编写 XML 解析代码时遇到的一个非常大的问题是,提供的大多数 “示例” 都太简单且完全是虚构的,对帮助不大 – 或者正好相反,它们使用非常复杂的自动生成的 XML 数据!
有人能给我一个提示吗?
提前致谢!
**编者按:**在发布此问题后,我在这里找到了一个简单的解决方案。
因此,我更新后的代码如下:from lxml import objectify root = objectify.fromstring(xml_string) # xml_string 包含上面的 XML 数据 print root.title # 返回书名 for para in root.abstract.iterchildren(): print para # 现在返回所有段落的文本 for keyword in root.keywordSet.iterchildren(): print keyword # 现在返回集合中的所有关键字
- 解决方案
- 使用 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
有关 XPath 语法的详细信息,请参阅 W3Schools 上的 XPath 教程。['First paragraph of the abstract', 'Second paragraph of the abstract'] ['First keyword', 'Second keyword', 'Third keyword']
具体来说,以上表达式中使用的元素使用- / 选择器选择根节点 / 直接子节点。
- text() 运算符选择各个元素的文本节点(“文本内容”)。
- 还可以使用 Objectify API 来完成此操作:
看起来 root.abstract.para 实际上是 root.abstract.para[0] 的简写。因此你需要明确使用 element.iterchildren() 来访问所有子元素。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
那不对,显然我们都误解了 Objectify API:
- 使用 XPath 来做这件事情相当简单: