2017-06-29 5 views
0

大規模なXMLファイルをJSONに解析する必要があるプロジェクトに取り組んでいます。私はコードを書いたが、遅すぎる。 lxmlBeautifulSoupを使用してみましたが、進める方法がわかりません。大量のXMLファイルをJSONに解析する

私のコードが含まれています。それはあまりにも遅いことを除いて、それが想定されているとおりに動作します。 100,000レコードを解析するために、100Mb以下のファイルを調べるのに約24時間かかりました。このようxml2jsonxml2dictなど

product_data = open('productdata_29.xml', 'r') 
read_product_data = product_data.read() 


def record_string_to_dict(record_string): 
'''This function takes a single record in string form and iterates through 
it, and sorts it as a dictionary. Only the nodes present in the parent_rss dict 
are appended to the new dict (single_record_dict). After each record, 
single_record_dict is flushed to final_list and is then emptied.''' 

    #Iterating through the string to find keys and values to put in to 
    #single_record_dict. 
    while record_string != record_string[::-1]: 

     try: 
      k = record_string.index('<') 

      l = record_string.index('>') 
      temp_key = record_string[k + 1:l] 
      record_string = record_string[l+1:] 
      m = record_string.index('<') 
      temp_value = record_string[:m] 

      #Cleaning thhe keys and values of unnecessary characters and symbols. 
      if '\n' in temp_value: 
       temp_value = temp_value[3:] 
      if temp_key[-1] == '/': 
       temp_key = temp_key[:-1] 

      n = record_string.index('\n') 
      record_string = record_string[n+2:] 

      #Checking parent_rss dict to see if the key from the record is present. If it is, 
      #the key is replaced with keys and added to single_record_dictionary. 
      if temp_key in mapped_nodes.keys(): 
       temp_key = mapped_nodes[temp_key] 
       single_record_dict[temp_key] = temp_value 

     except Exception: 
      break 


    while len(read_product_data) > 10: 

     #Goes through read_product_data to create blocks, each of which is a single 
     #record. 
     i = read_product_data.index('<record>') 
     j = read_product_data.index('</record>') + 8 
     single_record_string = read_product_data[i:j] 
     single_record_string = single_record_string[9:-10] 

     #Runs previous function with the input being the single string found previously. 
     record_string_to_dict(single_record_string) 

     #Flushes single_record_dict to final_list, and empties the dict for the next 
     #record. 
     final_list.append(single_record_dict) 
     single_record_dict = {} 

     #Removes the record that was previously processed. 
     read_product_data = read_product_data[j:] 

     #For keeping track/ease of use. 
     print('Record ' + str(break_counter) + ' has been appended.') 

     #Keeps track of the number of records. Once the set value is reached 
     #in the if loop, it is flushed to a new file. 
     break_counter += 1 
     flush_counter += 1 

     if break_counter == 100 or flush_counter == break_counter: 
      record_list = open('record_list_'+str(file_counter)+'.txt', 'w') 
      record_list.write(str(final_list)) 

      #file_counter keeps track of how many files have been created, so the next 
      #file has a different int at the end. 
      file_counter += 1 
      record_list.close() 

      #resets break counter 
      break_counter = 0 
      final_list = [] 
     #For testing purposes. Causes execution to stop once the number of files written 
     #matches the integer. 
     if file_counter == 2: 
      break 

    print('All records have been appended.') 
+0

[reproducible](https://stackoverflow.com/help/mcve)の例として、入力xmlと出力jsonを含めてください。 – Parfait

答えて

2

何らかの理由で、なぜあなたが検討されていないパッケージ。作業例については、この記事を参照してください。 How can i convert an xml file into JSON using python?

はポスト上記から再生

関連するコード:

xml2json

import xml2json 
s = '''<?xml version="1.0"?> 
    <note> 
     <to>Tove</to> 
     <from>Jani</from> 
     <heading>Reminder</heading> 
     <body>Don't forget me this weekend!</body> 
    </note>''' 
print xml2json.xml2json(s) 

xmltodict

import xmltodict, json 
o = xmltodict.parse('<e> <a>text</a> <a>text</a> </e>') 
json.dumps(o) # '{"e": {"a": ["text", "text"]}}' 

がで作業する場合は、この記事を参照してください。 Python 3: https://pythonadventures.wordpress.com/2014/12/29/xml-to-dict-xml-to-json/

import json 
import xmltodict 

def convert(xml_file, xml_attribs=True): 
    with open(xml_file, "rb") as f: # notice the "rb" mode 
     d = xmltodict.parse(f, xml_attribs=xml_attribs) 
     return json.dumps(d, indent=4) 
+0

ここでは、JSONファイルの最後に要素を追加するために、ここでitem_callback引数を試してみます。確かに、辞書としてのファイル全体がメモリを保持できるかどうかは分かりません。詳細については、ヘルプ(xmltodict.parse)を参照してください。 –

0

あなたは間違いなく、XMLを手作業で解析することにしたくありません。他のライブラリと同様に、XSLT 3.0プロセッサを使用することもできます。 100Mbを超えるためには、Saxon-EEのようなストリーミングプロセッサのメリットがありますが、オープンソースのSaxon-HEがそのようなレベルまでそれをハックできるはずです。ソースXMLまたはターゲットJSONを表示していないので、特定のコードを指定することはできません.XSLT 3.0では、既成の変換ではなくカスタマイズされた変換が必要なことが前提です。入力XMLのさまざまな部分をどのように処理するかを定義するテンプレートルールを記述します。

関連する問題