检查xml属性&使用Python 3.4附加元素

时间:2017-04-16 13:28:51

标签: python xml python-3.x elementtree

我想遍历子元素和元素并检查它们的属性。如果缺少某个属性值,它应该附加一个带有该属性值的空元素。

所以:

<app>        
    <rdg wit="#W_1956">Im Restaurant </rdg>               
    <rdg wit="#W_2002">Im Restaurant </rdg>
    <rdg wit="#W_2010">Im Restaurant </rdg>
</app>

我想添加一个元素

<rdg wit="#W_1999"/>

我的Python代码如下所示:

for app in root.findall('app'):
    if  '#W_1956' not in ET.Element('rdg').attrib:
        new_tag = ET.SubElement(app, 'rdg')

        new_tag.attrib['wit'] = '#W_1956' 
    if  '#W_1999' not in ET.Element('rdg').attrib:
        new_tag = ET.SubElement(app, 'rdg')

        new_tag.attrib['wit'] = '#W_1999'   

这给了我这个XML:

<app>        
    <rdg wit="#W_1956">Im Restaurant </rdg>
    <rdg wit="#W_2002">Im Restaurant </rdg>
    <rdg wit="#W_2010">Im Restaurant </rdg>
    <rdg wit="#W_1956"/>
    <rdg wit="#W_1999"/>
</app>

因此即使源中有一个带有W_1956属性的元素,它仍会添加它。我也试过findall('rdg'),但这也不起作用(输出XML保持完全不变)。现在我不知道错误是在if语句中,在elementree-(sub)元素中的某个地方,还是代码完全错误。

2 个答案:

答案 0 :(得分:0)

尝试使用显式属性。例如:

.
.
.
if  '#W_1956' not in ET.Element('rdg').attrib['wit']
.
.
.

答案 1 :(得分:0)

通过保存到单独的列表中,考虑从文档的整个rgd属性列表中有条件地检查。然后,迭代地检查值以添加或不添加新元素,所有这些都使用etree的解析将XML属性呈现为具有键/值对的Python字典的事实。

import xml.etree.ElementTree as ET

txt ='''<app>        
    <rdg wit="#W_1956">Im Restaurant </rdg>               
    <rdg wit="#W_2002">Im Restaurant </rdg>
    <rdg wit="#W_2010">Im Restaurant </rdg>
</app>'''

root = ET.fromstring(txt)

# LIST OF ALL ATTRIBUTE DICTS
attrdict = [app.attrib for app in root.findall('./rdg')]
# LIST OF ALL ATTRIBUTE VALUES
attrvals = [v for i in attrdict for k,v in i.items()]

# ITERATE THROUGH ATTRIB VALUES AND ADD TO ROOT IF DOES NOT EXIST
for i in ['#W_1956', '#W_1999']:
    if  i not in attrvals:
        new_tag = ET.SubElement(root, 'rdg')
        new_tag.attrib['wit'] = i

# OUTPUT TO STRING
print(ET.tostring(root).decode('UTF-8'))
# <app>        
#    <rdg wit="#W_1956">Im Restaurant </rdg>               
#    <rdg wit="#W_2002">Im Restaurant </rdg>
#    <rdg wit="#W_2010">Im Restaurant </rdg>
# <rdg wit="#W_1999" /></app>

# OUTPUT TO FILE
ET.ElementTree(root).write('myoutput.xml', encoding="UTF-8", xml_declaration=True)