[英]Write xml with a path and value
I have a list of paths and values, something like this: 我有一个路径和值的列表,像这样:
[
{'Path': 'Item/Info/Name', 'Value': 'Body HD'},
{'Path': 'Item/Genres/Genre', 'Value': 'Action'},
]
And I want to build out the full xml structure, which would be: 我想构建完整的xml结构,即:
<Item>
<Info>
<Name>Body HD</Name>
</Info>
<Genres>
<Genre>Action</Genre>
</Genres>
</Item>
Is there a way to do this with lxml
? 有没有办法用
lxml
做到这一点? Or how could I build a function to fill in the inferred paths? 或者我该如何构建一个函数来填充推断的路径?
Yes, you can do that with lxml
. 是的,您可以使用
lxml
做到这一点。
I suggest you to use a template XML and fill it. 我建议您使用模板XML并填充它。
Template: 模板:
<Item>
<Info>
<Name/>
</Info>
<Genres>
<Genre/>
</Genres>
</Item>
from lxml import etree
tree = etree.parse("template.xml")
Then, fill it: 然后,填写:
entries = [
{'Path': 'Item/Info/Name', 'Value': 'Body HD'},
{'Path': 'Item/Genres/Genre', 'Value': 'Action'}]
for entry in entries:
xpath = entry["Path"]
node = tree.xpath(xpath)[0]
node.text = entry['Value']
Note: instead of "Path", I would prefer "XPath" 注意:我希望使用“ XPath”代替“ Path”
If you dont want template, you can generate the whole tree structure like this: 如果您不想要模板,则可以像这样生成整个树结构:
from lxml import etree
entries = [
{'Path': 'Item/Info/Name', 'Value': 'Body HD'},
{'Path': 'Item/Genres/Genre', 'Value': 'Action'}]
root = None
for entry in entries:
path = entry["Path"]
parts = path.split("/")
xpath_list = ["/" + parts[0]] + parts[1:]
curr = root
for xpath in xpath_list:
name = xpath.strip("/")
if curr is None:
root = curr = etree.Element(name)
else:
nodes = curr.xpath(xpath)
if nodes:
curr = nodes[0]
else:
curr = etree.SubElement(curr, name)
curr.text = entry["Value"]
print(etree.tostring(root, pretty_print=True))
The result is: 结果是:
<Item>
<Info>
<Name>Body HD</Name>
</Info>
<Genres>
<Genre>Action</Genre>
</Genres>
</Item>
Of course, there are limitations. 当然有局限性。
You could do something like: 您可以执行以下操作:
l = [
{'Path': 'Item/Info/Name', 'Value': 'Body HD'},
{'Path': 'Item/Genres/Genre', 'Value': 'Action'},
]
import lxml.etree as et
root_node = l[0]["Path"].split("/", 1)[0]
tree = et.fromstring("<{}></{}>".format(root_node, root_node))
for dct in l:
nodes = iter(dct["Path"].split("/")[1:])
# catch path like Item/Foo where there is only one child.
nxt_child = child = et.Element(next(nodes))
for node in nodes:
# keep adding nodes
nxt_child = et.Element(node)
child.append(nxt_child)
# set value to last node.
nxt_child.text = dct["Value"]
# append it to the tree.
tree.append(child)
print(et.tostring(tree))
Which would give you: 这会给你:
<Item>
<Info>
<Name>Body HD</Name>
</Info>
<Genres>
<Genre>Action</Genre>
</Genres>
</Item>
You know Item
is the root node and the first in every Path, so first create a tree using that node and then just add to the tree as you go. 您知道
Item
是根节点,并且是每个Path中的第一个节点,因此首先使用该节点创建树,然后随便添加到树中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.