lxml,在元素之间获取xml

时间:2015-02-17 11:17:25

标签: python xml xpath

给出这个样本xml:

<xml>
<pb facs="id1" />
  <aa></aa>
  <aa></aa>
  <lot-of-xml></lot-of-xml>
<pb facs="id2" />
  <bb></bb>
  <bb></bb>
  <lot-of-xml></lot-of-xml>
</xml>

我需要解析它并获得所有 pb之间的内容,并保存到不同的外部文件中。

预期结果:

$ cat id1
  <aa></aa>
  <aa></aa>
  <lot-of-xml></lot-of-xml>

$ cat id2
  <bb></bb>
  <bb></bb>
  <lot-of-xml></lot-of-xml>

使用什么是正确的xpath ax?

from lxml import etree
xml = etree.parse("sample.xml")

for pb in xml.xpath('//pb'):
    filename = pb.xpath('@facs')[0]
    f = open(filename, 'w')

    content =  **{{ HOW TO GET THE CONTENT HERE? }}**

    f.write(content)
    f.close()

是否有任何xpath表达式来获取所有后代并在到达新pb时停止?

2 个答案:

答案 0 :(得分:0)

好的,我测试了这段代码:

lists = []
for node in tree.findall('*'):
    if node.tag == 'pb':
        lists.append([])
    else:
        lists[-1].append(node)

输出:

>>> lists
[[<Element test at 2967fa8>, <Element test at 2a89030>, <Element lot-of-xml at 2a89080>], [<Element test at 2a89170>, <Element test at 2a891c0>, <Element lot-of-xml at 2a89210>]]

输入文件(以防万一):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xml>
<pb facs="id1" />
  <test></test>
  <test></test>
  <lot-of-xml></lot-of-xml>
<pb facs="id2" />
  <test></test>
  <test></test>
  <lot-of-xml></lot-of-xml>
</xml>

答案 1 :(得分:0)

你想在两个pb之间提取标签吗?如果是,那么这是不可能的,因为它不是pb之间的标签而不是与pb处于同一级别的单个标签,因为您关闭了标签pb。如果在测试标记之后关闭标记,则测试可以成为pb的子项。

换句话说,如果你的xml是这样的:

<xml>
<pb facs="id1">
  <test></test>
</pb>
  <test></test>
<pb facs="id2" />
  <test></test>
  <test></test>
</xml>

然后你可以使用

import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')
root = tree.getroot()
for child in root:
    for subchild in child:
        print subchild

以pb作为父项打印子项('test')。 好吧,如果不是这种情况(你只想提取pb标签的属性),那么你可以使用下面显示的两种方法中的任何一种来提取元素。 使用python的内置etree

import xml.etree.ElementTree as ET
tree = ET.parse('sample.xml')
root = tree.getroot()
for child in root:
   if child.get('facs'):
       print child.get('facs')

使用lxml库,您可以像这样解析它:

tree = etree.parse('test.xml')
root = tree.getroot()
for child in root:
    if child.get('facs'):
        print child.get('facs')