python lxml 中的 XQuery 绝对路径

XQuery absolute path in python lxml

我有一个 XML 文档,我想从中提取特定节点 (mynode) 的绝对路径供以后使用。我这样检索节点:

from StringIO import StringIO
from lxml import etree

xml = """
<a1>
    <b1>
        <c1>content1</c1>
    </b1>
    <b1>
        <c1>content2</c1>
    </b1>
</a1>"""
root = etree.fromstring(xml)

i = 0
mynode = root.xpath('//c1')[i]

为了得到我目前使用的路径

ancestors = mynode.xpath('./ancestor::*')
p = ''.join( map( lambda x: '/' + x.tag , ancestors ) + [ '/' , mynode.tag ] )

p 现在有值

/a1/b1/c1

但是为了存储路径供以后使用,我还必须存储第一个代码片段中的索引 i 以便检索正确的节点,因为对 p 的 xpath 查询将包含两个节点 c1。我不想存储该索引。

最好是包含索引的 xquery 路径。对于第一个 c1 节点,它可能如下所示:

/a1/b1[1]/c1

或者第二个 c1 节点

/a1/b1[2]/c1

有人知道如何实现吗? 是否有另一种方法来指定一个节点并稍后访问它?

from lxml import etree
from io import StringIO, BytesIO

# ----------------------------------------------

def node_location(node):
    position = len(node.xpath('./preceding-sibling::' + node.tag)) + 1
    return '/' + node.tag + '[' + str(position) + ']'

def node_path(node):
    nodes = mynode.xpath('./ancestor-or-self::*')
    return ''.join( map(node_location, nodes) )

# ----------------------------------------------

xml = """
<a1>
    <b1>
        <c1>content1</c1>
    </b1>
    <b1>
        <c1>content2</c1>
    </b1>
</a1>"""

root = etree.fromstring(xml)

for mynode in root.xpath('//c1'):
    print node_path(mynode)

打印

/a1[1]/b1[1]/c1[1]
/a1[1]/b1[2]/c1[1]

Is there another method to specify a node and access it later on?

如果你的意思是"persist across separate invocations of the program",那么不,不是真的。