lxml etree之前找到最接近的元素

时间:2015-06-23 17:24:57

标签: python xml xpath xml-parsing elementtree

xml文档具有如下结构

import csv  
import re  

in_file = open("/test.csv", "rb")  
reader = csv.reader(in_file)  
out_file = open("/out.csv", "wb")  
writer = csv.writer(out_file)  

for row in reader:   
    newrow = re.sub(r"(\.)+", ",", row)  
    writer.writerow(newrow)

in_file.close()  
out_file.close()

我的解析器首先获取所有<a> <b> <d> </b> <c attr1="important"/> <b> <d> </b> <c attr1="so important" /> <b></b> </a> 元素

<d>

现在的任务是:

在当前from lxml import etree xmltree = etree.parse(document) elems = xmltree.xpath('//d') 代码之前,从最近的<c>代码获取属性(如果有)。

天真的做法是做类似下面的事情

<d>

但对我而言,这看起来并不简单 - 我是否遗漏了文档中的内容?如何在不实现自己的迭代器的情况下解决这个问题?

1 个答案:

答案 0 :(得分:3)

使用preceding axis

  

前一轴表示文档中上下文节点之前的所有节点,除了祖先,属性和命名空间节点。

for el in elems:
    try:
        print el.xpath("preceding::c[@attr1]")[-1].get("attr1")
    except IndexError:
        print "No preceding 'c' element."

演示:

>>> from lxml import etree
>>> 
>>> data = """
... <a>
...     <b>
...         <d/>
...     </b>
... 
...     <c attr1="important"/>
...     <b>
...         <d/>
...     </b>
...     <c attr1="so important" />
...     <b></b>
... </a>
... """
>>> xmltree = etree.fromstring(data)
>>> elems = xmltree.xpath('//d')
>>> 
>>> for el in elems:
...     try:
...         print el.xpath("preceding::c[@attr1]")[-1].get("attr1")
...     except IndexError:
...         print "No preceding 'c' element."
... 
No preceding 'c' element.
important