2015-12-16 4 views
1

Язык: - Python Размер 2.7.6Modify большой файл XML с помощью LXML

Файл: - 1,5 Гб

XML Format

<myfeed> 
    <product> 
     <id>876543</id> 
     <name>ABC</name> 
     .... 
    </product> 

    <product> 
     <id>876567</id> 
     <name>DEF</name> 
     .... 
    </product> 

    <product> 
     <id>986543</id> 
     <name>XYZ</name> 
     .... 
    </product> 

Я должен

А) Читать все узлы <product>

B) Удалите некоторые из этих узлов (еслитекст 210 атрибута в питона наборе()

C) Update/Alter несколько узлов (если текст атрибута <id> в питона Словаре

D) Append/запись некоторых новых узлов

Проблема в том, что я XML-файл огромен (около 1,5 ГБ). Я сделал некоторые исследования и решил использовать lxml для всех этих целей.

Я пытаюсь использовать iterparse() с element.clear() для достижения этого, потому что он не будет потреблять всю мою память.

for event, element in etree.iterparse(big_xml_file,tag = 'product'): 
     for child in element: 
      if child.tag == unique_tag: 
       if child.text in products_id_hash_set_to_delete: #python set() 
        #delete this element node 

       else: 
        if child.text in products_dict_to_update: 
         #update this element node 
         else: 
          print child.text 
     element.clear() 

Примечание: - Я хочу, чтобы достичь все эти 4 задачи в одном сканировании файла XML

Вопросы

1) Могу ли я достичь всего этого в одном сканировании файла?

2) Если да, как удалить и обновить узлы элементов, которые я обрабатываю?

3) Должен ли я использовать tree.xpath() вместо этого? Если да, сколько памяти он будет потреблять за 1,5 ГБ файла или работает так же, как и iterparse()

Я не очень опытен в python. Я из фона Java.

ответ

2

Вы не можете редактировать XML-файл на месте. Вы должны записать вывод в новый (временный) файл, а затем заменить исходный файл на новый файл.

Так основной алгоритм:

  • Цикл по всем элементам.
  • Если узел один удалить, перейдите к следующему элементу
  • Если узел один, чтобы изменить, изменить его значение
  • Выпишите узел «« «Это ключевой бит вам не хватает
  • Когда вы собираетесь закончить обработку узла, который является родителем одного из новых узлов, запишите новый узел и удалите его из коллекции новых узлов.
  • Закрыть выходной файл
  • Переименовать.

Чтобы ответить на дополнительный вопрос: вам нужно понять, что XML-файл является (длинной) строкой символов.Если вы хотите вставить символ, вы должны перетасовать все остальные; если вы хотите удалить персонажа, вы должны перетасовать все остальные. Вы не можете сделать это с файлом; вы не можете просто удалить символ из середины файла.

Если у вас есть миллионы элементов (и это настоящая проблема, а не упражнение для класса), вам необходимо использовать базу данных. SQLite - это моя первая мысль, когда кто-то говорит «база данных», но, как указывает Чарльз Даффи ниже, база данных XQuery, вероятно, станет лучшим местом для начала, поскольку у вас уже есть XML. См. BaseX или eXist для некоторых версий с открытым исходным кодом.

+0

Невозможно ли редактировать XML на месте? Если не в python, чем может быть на Java или на любом другом языке (я понимаю, что этот процесс зависит от ОС). Как работает команда «sed -i»? sed также переносит отредактированный контент в новый файл? – shiva

+0

Мой файл очень большой (миллионы элементов ), и мне нужно удалить и обновить только несколько (может быть 300-500) элементов . Сколько времени потребуется, чтобы написать весь файл снова? – shiva

+0

В соответствии с этим ответом «sed -i» также записывает весь файл и переименовывает его за кулисами. http://stackoverflow.com/questions/12696125/solaris-sed-edit-the-file-in-place – shiva

Смежные вопросы