我有一个大型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>
答案 0 :(得分:0)
我会将SAX Parser用于这么大的XML文件:
您正在做的示例代码:
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"))