Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用lxml读取xml并比较元素_Python_Xml_Lxml - Fatal编程技术网

Python 使用lxml读取xml并比较元素

Python 使用lxml读取xml并比较元素,python,xml,lxml,Python,Xml,Lxml,我尝试在StackOverflow上搜索各种问题和答案,但找不到适合我情况的解决方案,所以这是我的问题 我尝试比较3个xml文件。我遇到的问题是一次抓取“主”XML文件的部分并将信息保存在一起。例如,我希望保留与1关联的信息,并能够使用脚本中的每个片段 这个XML文件在标记之间可以有任意数量的字段,但我只需要5个特定字段。我对Python相当陌生,而且对使用Python阅读文本文件非常陌生,如果有任何帮助,我将不胜感激 下面是xml的一个示例 Main XML: <?xml ver

我尝试在StackOverflow上搜索各种问题和答案,但找不到适合我情况的解决方案,所以这是我的问题

我尝试比较3个xml文件。我遇到的问题是一次抓取“主”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>
我知道我在某个地方做错了什么,xml的格式(我无法在源代码处更改)也帮不上忙


我收到的错误是“AttributeError:“list”对象没有“getchildren”属性

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'}]
可能在一行中的额外字段将在字段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)

如果更方便的话,您可以将所有_数据定义为一个字典,并对键使用id,每个键的值可以是一个包含其余数据的字典。

您可以发布您当前的代码吗?我添加了我收到的最新尝试和错误。xpath()返回元素对象的列表--但不管列表中有什么,都不能编写[1,2,3].getchildren(),因为python没有为列表提供该方法。感谢您的及时回复,我认为这是一个基于错误的“存储”问题。我不知道如何纠正这个问题。我仍然需要过滤掉所有额外的字段,我提供的示例只包含了一个我需要的示例。xml本身可以在每一组标记之间包含多达15个额外字段。@MikeS.,我添加了一个带有过滤器的示例。再次感谢您,我不能相信我忽略了使用集合来过滤信息。我投票支持这个答案,只要页面从发布此评论中重新加载。1)你可以使用一个允许姓名的列表--“in”在列表中也起作用--它只是没有设置查找那么快。2) 您可以使用一个字典,其中键是允许的名称,它们的每个值都是True,然后您可以编写…如果允许的话\u names.get(name\u val,False):field\u dict[name\u val]=field.text。我一定会研究其他选项,我的总体目标是最终将此xml与其他两个文件进行比较,并创建一个输出,其中列出了其他两个文件中没有的值。在python程序的当前部分,这对我来说是巨大的帮助。我分阶段/分部分地编写程序,使事情变得更容易一些。
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)