2017-11-07 23 views
1

私は大きなXMLファイル(1.5GB)を持っています。それは<node>という要素で構成され、各ノード要素は "id"属性<node id = "834839483"/>を持っています。大規模なXMLファイルで重複する "id"属性を持つ重複する要素を見つける

idを重複しているノードをファイルから検索し、IDをキーに、それぞれの重複の数を値として辞書またはその他の構造を生成したい場合は、「重複が見つかりません」と表示します。

私はファイルの10分の1のサイズで動作するものを書いています。

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を把握する必要があるため、これを解決する方法はわかりません。

EDIT:ここ 私はこのような大規模なXMLファイルのSAXパーサを使用するファイル

<?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

データが実際に大きすぎる場合は、IDを範囲に分割し、特定の範囲内の特定の範囲外のすべてのIDを無視することを検討します。次に、複数のパスを各範囲に1つずつ実行します。それはあなたのカウンターにあなたが持っているアイテムの数を制限することができます。 –

+0

いくつかの入力XMLフラグメントを投稿した場合は助けになる – RomanPerekhrest

+0

IDのリストを作成したら、これはhttps://stackoverflow.com/questions/2600191/how-cani-i-とほぼ同じですピリオド内のitem-of-a-item-of-item-itemをカウントすることはできません。おそらく、カウントがゼロのIDを含むことは望ましくありません。 – Acccumulation

答えて

0

の例である:

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")) 
関連する問題