Python lxml 处理嵌套元素

给定如下 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 # 现在返回集合中的所有关键字
    
  1. 解决方案
    • 使用 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']
      
      有关 XPath 语法的详细信息,请参阅 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 实际上是 root.abstract.para[0] 的简写。因此你需要明确使用 element.iterchildren() 来访问所有子元素。
      那不对,显然我们都误解了 Objectify API:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值