如何在Python中使用XPath填充XML文件

5 投票
1 回答
2358 浏览
提问于 2025-04-16 15:43

我有一个针对XML文件中某个节点的xpath,但这个节点现在还不存在。我想用这个xpath来生成这个节点。我开始写一个函数来实现这个功能,但在想是否有现成的库可以帮我节省一些时间?我现在在用pyxml,但也在考虑换成ElementTree。所以我想明确一下,我想要的是:

root/foo/bar

生成:

<root>
  <foo>
    <bar>
    </bar>
  </foo>
</root>

我怀疑这样的函数的行为可能没有明确的定义,所以一般情况下可能没有人去做这个。不过我还是想问问,万一有人有好的建议呢?我还有这个文件的DTD,如果有帮助的话可以提供。

1 个回答

3

没有找到现成的解决方案,但使用ElementTree(或者其他的xml库也可以——我只是对ElementTree更熟悉)应该是比较简单的。

下面的代码片段似乎可以满足所需的有限的xpath功能:

# -*- coding: utf-8 -*-
from xml.etree import ElementTree as ET

def build_xpath(node, path):
    components = path.split("/")
    if components[0] == node.tag:
        components.pop(0)
    while components:
        # take in account positional  indexes in the form /path/para[3] or /path/para[location()=3]
        if "[" in components[0]:
            component, trail = components[0].split("[",1)
            target_index = int(trail.split("=")[-1].strip("]"))
        else:
            component = components[0]
            target_index = 0
        components.pop(0)
        found_index = -1
        for child in node.getchildren():
            if child.tag == component:
                found_index += 1
                if found_index == target_index:
                    node = child
                    break
        else:
            for i in range(target_index - found_index):
                new_node = ET.Element(component)
                node.append(new_node)
            node = new_node


if __name__  == "__main__":
    #Example
    root = ET.Element("root")
    build_xpath(root, "root/foo/bar[position()=4]/snafu")
    print ET.tostring(root)

撰写回答