首页 > 解决方案 > 从 for 循环内部将多个元素插入 xml 时的字符串插值

问题描述

出于某种原因,我发现很难通过从for循环中插入多个节点来生成 XML 文件。以下确实实现了这一点,但仍然存在几个问题。

给定一个字典列表

dict_list = [{'x': 'abc', 'y': 'efg'}, \
            {'x': 'hij', 'y': 'klm'}]

我可以objectify()用来生成所需的 xml:

from lxml import etree, objectify
end_game = etree.XML('<final_root/>')

E = objectify.ElementMaker(annotate=False)
tmp_root = E.entry
for d in dict_list:
    att_values = [val for val in d.values()]    
    doc = tmp_root(   
        x = att_values[0],
        y = att_values[1]
     )    
    end_game.append(doc)
print(etree.tostring(end_game, pretty_print=True).decode())

根据需要输出:

<final_root>
  <entry x="abc" y="efg"/>
  <entry x="hij" y="klm"/>
</final_root>

问题是我需要将属性名称硬连接xy循环中。尝试使用字符串插值失败。例如:

for d in dict_list:
     att_items = [item for item in d.items()] 
        doc = tmp_root(   
            att_items[0][0] = att_items[0][1],
            att_items[1][0] = att_items[1][1]
         )

提高

SyntaxError: 表达式不能包含赋值,也许你的意思是“==”?

使用 f 字符串 ( 'f'{att_items[0][0]}' = att_items[0][1]) 或格式 ( {}.format(att_items[0][0]) = att_items[0][1]) 会引发相同的错误。

那么,显而易见的问题是:有没有办法避免手动插入属性名称?或者:是否可以使用代替来复制结果(并可能避免问题)lxml.etree

标签: lxmllxml.objectify

解决方案


由于etree Elements 将属性作为 dict 携带,因此您应该能够在构造 Element 时只传入 dict ...

from lxml import etree

end_game = etree.XML('<final_root/>')

dict_list = [{'x': 'abc', 'y': 'efg'},
             {'x': 'hij', 'y': 'klm'}]

for meta in dict_list:
    end_game.append(etree.Element('item', meta))

print(etree.tostring(end_game, pretty_print=True).decode())

打印输出...

<final_root>
  <item x="abc" y="efg"/>
  <item x="hij" y="klm"/>
</final_root>

推荐阅读