我已尝试在StackOverflow上搜索各种问题和答案,但无法找到适合我情况的解决方案,所以这是我的问题。
我有3个xml文件,我试图比较。我遇到的问题是一次抓取“Main”XML文件的各个部分并将信息保存在一起。例如,我想保留与1相关的信息,并能够使用脚本中的每个部分。
此XML文件可以在标记之间包含任意数量的字段,但我只需要5个特定字段。我是Python的新手,使用Python阅读文本文件非常新,任何帮助都将不胜感激。
xml的示例如下。
Main XML:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<resultset table="foo_bar">
<row>
<field name="id">1</field>
<field name="name">foo 1</field>
<field name="item 1">bar 1</field>
<field name="item 2">Accepted</field>
<field name="item 3">Accepted</field>
</row>
<row>
<field name="id">2</field>
<field name="name">foo 2</field>
<field name="item 1">bar 2</field>
<field name="item 2">Declined</field>
<field name="item 3">Accepted</field>
</row>
<row>
<field name="id">3</field>
<field name="name">foo 3</field>
<field name="item 1">bar 3</field>
<field name="item 2">Accepted</field>
<field name="item 3">Declined</field>
</row>
.....Continues
</resultset>
我尝试过针对类似问题的各种答案,但到目前为止都没有成功。
编辑我尝试了多种方法,我将不得不深入研究各种.py脚本来查找所有这些内容。以下是基于here
问题的最新信息from lxml import etree as ET
def filter_by_itemid(doc, idlist):
rowset = doc.xpath("//row")
for elem in rowset.getchildren():
if elem.get("*") not in idlist:
rowset.remove(elem)
return doc
doc = ET.parse("my.xml")
filter_by_itemid(doc, ['id', 'name', 'item 1', 'item 2', 'item 3'])
print(ET.tostring(doc))
我知道我在某处做错了,xml的格式化(我无法在源头改变)没有帮助......
我收到的错误是“AttributeError:'list'对象没有属性'getchildren'”
答案 0 :(得分:2)
这样的事情怎么样:
from lxml import etree
root = etree.parse('xml.xml')
rows = root.findall('row')
all_data = []
for row in rows:
field_dict = {}
fields = row.findall('field')
for field in fields:
field_dict[field.get('name')] = field.text
print(field_dict)
all_data.append(field_dict)
print(all_data)
--output:--
{'item 3': 'Accepted', 'item 2': 'Accepted', 'item 1': 'bar 1', 'id': '1', 'name': 'foo 1'}
{'item 3': 'Accepted', 'item 2': 'Declined', 'item 1': 'bar 2', 'id': '2', 'name': 'foo 2'}
{'item 3': 'Declined', 'item 2': 'Accepted', 'item 1': 'bar 3', 'id': '3', 'name': 'foo 3'}
[{'item 3': 'Accepted', 'item 2': 'Accepted', 'item 1': 'bar 1', 'id': '1', 'name': 'foo 1'}, {'item 3': 'Accepted', 'item 2': 'Declined', 'item 1': 'bar 2', 'id': '2', 'name': 'foo 2'}, {'item 3': 'Declined', 'item 2': 'Accepted', 'item 1': 'bar 3', 'id': '3', 'name': 'foo 3'}]
可能在一行中的额外字段将在field_dict中,但您可以忽略它们。或者,如果这对您不起作用,您可以过滤掉垃圾:
from lxml import etree
root = etree.parse('xml.xml')
rows = root.findall('row')
#Create a set:
allowed_names = {
'id',
'name',
'item 1',
'item 2',
'item 3'
}
all_data = []
for row in rows:
field_dict = {}
fields = row.findall('field')
for field in fields:
name_val = field.get('name')
if name_val in allowed_names:
field_dict[name_val] = field.text
print(field_dict)
all_data.append(field_dict)
print(all_data)
如果它更方便,你可以将all_data定义为字典,并使用id作为键,每个键的值可以是包含其余数据的字典。