【问题标题】:lxml etree find closest element beforelxml etree在之前找到最近的元素
【发布时间】:2015-09-09 15:30:28
【问题描述】:

xml 文档的结构如下所示

<a>
    <b>
        <d>
    </b>

    <c attr1="important"/>
    <b>
        <d>
    </b>
    <c attr1="so important" />
    <b></b>
</a>

我的解析器首先获取所有 &lt;d&gt; 元素

from lxml import etree
xmltree = etree.parse(document)
elems = xmltree.xpath('//d')

现在的任务是:

从最近的&lt;c&gt;标签中获取属性当前&lt;d&gt;标签之前,如果有的话。

天真的方法是做如下的事情

for el in elems:
    it = el.getparent()
    while it != None and it.tag != 'c':
        prev = it.getprevious()
        if prev == None:
            it = it.getparent()
        else:
            it = prev

    if it != None:
        print el, it.get("attr1")

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

【问题讨论】:

    标签: python xml xpath xml-parsing elementtree


    【解决方案1】:

    使用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
    

    【讨论】:

    • 因为我需要最接近的,我认为应该是el.xpath("preceding::c[@attr1]")[-1] 不是吗?其他一切:非常感谢您
    猜你喜欢
    • 2015-09-10
    • 2014-03-13
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2016-04-03
    • 2020-08-30
    • 2019-03-11
    相关资源
    最近更新 更多