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

5

我有一个xpath表达式用于查找在xml文件中还不存在的节点,我想要使用它来生成所需的节点。我已经开始编写一个函数来完成此任务,但是想知道是否有现成的库可以帮助我完成并节省时间?目前我正在使用pyxml,但考虑将其移植到ElementTree上。所以我想要:

root/foo/bar

生产:

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

我觉得这种函数的行为在一般情况下定义不够清晰,以至于没人特别介意,但我还是想提出来。如果需要,我也有文件的DTD。


乍一看,基于XPath“_stricto sensu_”创建这样的元素似乎是不可能的。例如,对于//foo/bar会生成什么呢?另一方面,似乎可以基于XPath的子集生成XML - 实际上这似乎是一个好主意。 - brandizzi
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)

1
如何在这里处理属性? - user2728203

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接