Мне нужно проанализировать очень большие XML-файлы (в диапазоне 3-5 ГБ), которые должны разбиваться на несколько меньших XML-файлов в соответствии с данными, включенными в узлы XML.
Каждый входной файл включает несколько сотен тысяч<measure>
элементов, как в этом (очень) упрощенном фрагменте.
<items>
<measure code="0810">
<condition sequ="001" SID="-5041162"/>
<footnote Id="00550"/>
<footnote Id="00735"/>
</measure>
<measure code="6304">
<component Id="01" national="1"/>
<footnote Id="00001"/>
</measure>
<measure code="0811">
<condition sequ="002" SID="-5041356"/>
<footnote Id="00555"/>
</measure>
<measure code="2915">
<component Id="01" national="0"/>
<certif SID="-737740"/>
<certif SID="-737780"/>
</measure>
</items>
Содержимое фактических <measure>
элементов может быть почти любым правильно сформированным XML.
Мне нужновыполните два процесса при анализе этих файлов:
- Извлечение информации из содержимого элементов
<measure>
и выгрузка ее в базу данных MongoDB (эта часть решена ...) - Разделить исходный XML-файл, скажем, на 100, XML-подфайлов на основе первых двух цифр атрибута «code» каждого узла
<measure>
. То есть необходимо создать 100 новых XML-файлов (от «part_00.xml» до «part_99.xml»), и каждый элемент <measure>
должен быть добавлен в соответствующий субфайл. Т.е. <measure>
блоки 1 и 3 в примере должны быть скопированы в 'part_08.xml', блок 2 должен быть скопирован в 'part_63.xml' ...
Я использую SAX дляРазбор исходных файлов, и процесс 1 выше работает хорошо. Чистый скелет процесса SAX:
import sys
from xml.sax import ContentHandler
from xml.sax import make_parser
class ParseMeasures(ContentHandler):
code = ''
def startElement(self, name, attrs):
if name == 'measure':
self.code = attrs.get('code')
def endElement(self, name):
if name == 'measure':
print('***Must append <measure> block to file part_{0}.xml'.format(self.code[:2]))
def main(args):
handler = ParseMeasures()
sax_parser = make_parser()
sax_parser.setContentHandler(handler)
sax_parser.parse('my_large_xml.file.xml')
print('Ended')
if __name__ == '__main__':
main(sys.argv[1:])
Мне нужно было бы иметь возможность получить доступ ко всему XML-элементу <measure>
в endElement (), чтобы добавить его в соответствующий субфайл.
Есть ли способ объединить SAX с другими функциями синтаксического анализа XML, который позволит получить весь элемент XML <measure>
в endElement ()? (Я могу справиться с созданием и управлением подфайлами ... Это не проблема!)
Или, может быть, SAX-подход не самый адекватный в этой ситуации, для начала?
Единственное предостережение в том, что процесс должен обрабатывать входные файлы в диапазоне 3-5 Гб ...