查找具有重复" id"的重复元素大型XML文件中的属性

时间:2017-11-07 15:43:37

标签: python xml elementtree

我有一个大型XML文件(1.5GB)。它由名为<node>的元素组成,每个节点元素都有一个&#34; id&#34;属性<node id = "834839483"/>

我想在文件中搜索具有重复ID的节点,并生成一个字典或其他结构,其中id为键,每个重复的数量为值,或打印&#34;未找到重复项#34;如果适用的话。

我写了一些适用于文件大小十分之一的文件。

import xml.etree.cElementTree as ET
import pprint
from collections import Counter

def find_node_id_dups(filename):
    node_id_dups = set()
    empty_set = set()
    empty_set.add("None")
    node_counter=Counter()
    x=False

    for _, element in ET.iterparse(filename):
        if element.tag =="node":
            katt = element.attrib['id']
            node_counter[katt]+=1
    for id_num in node_counter:
        if node_counter[id_num] != 1:
            node_id_dups.add(id_num)
            x=True
    if x == False:
        return empty_set
    return node_id_dups    

node_id_dups = find_node_id_dups(REAL_FILE)

print("Node Id Duplicates\n")
print("\n".join(sorted(list(node_id_dups))))

我认为这将是一种快速的搜索方式,因为它只需要读取每个元素两次,但最后我仍然试图将1.5 GB的数据填充到一个计数器对象中。

我不知道如何解决这个问题,因为理论上我需要抓住每个id直到最后,因为在搜索的任何阶段都可以找到重复。

编辑: 以下是文件

的示例
<?xml version="1.0" encoding="UTF-8"?>

<osm>

<node changeset="7632877" id="27195852" lat="45.5408932" lon="-122.8675556" timestamp="2011-03-21T23:25:58Z" uid="393906" user="Grant Humphries" version="11">

    <tag k="addr:street" v="North Green St." />

</node>

<node changeset="7632878" id="27195856" lat="45.5408936" lon="-122.8675556" timestamp="2011-03-21T23:25:58Z" uid="393906" user="Grant Humphries" version="11">

    <tag k="addr:city" v="Lower case" />

</node>
<node changeset="7632878" id="27195856" lat="45.5408936" lon="-122.8675556" timestamp="2011-03-21T23:25:58Z" uid="393906" user="Grant Humphries" version="11">

    <tag k="addr:city" v="aower Lase" />

</node>
<node changeset="7632878" id="27195856" lat="45.5408936" lon="-122.8675556" timestamp="2011-03-21T23:25:58Z" uid="393906" user="Grant Humphries" version="11">

    <tag k="addr:city" v="aower Lase" />

</node>
</osm>

1 个答案:

答案 0 :(得分:0)

我会将SAX Parser用于这么大的XML文件:

SAX Parser DOC

ContentHandler class DOC

您正在做的示例代码:

import xml.sax

class MySaxHandler(xml.sax.ContentHandler):
    def startElement(self, name, attrs):
        # if element we are looking at is 'node'
        if name == "node":
            for key, val in attrs.items():
                if key == 'id':
                    if val not in self.my_nodes.keys():
                        self.my_nodes[val] = 1
                    else:
                        new_count = self.my_nodes[val] + 1
                        self.my_nodes[val] = new_count

    def startDocument(self):
        self.my_nodes = {}

    def endDocument(self):
        for key, val in self.my_nodes:
            print 'id: '+key+'  count: '+val

parser = xml.sax.make_parser()
parser.setContentHandler(MySaxHandler())
parser.parse(open("your_filename.xml","r"))