Я пытаюсь удалить все узлы project1
(вместе с их дочерними элементами) из приведенного ниже образца документа xml (оригинал документа составляет около 30 ГБ) с использованием анализатора SAX. Было бы замечательно иметь отдельный измененный файл или ok с встроенным редактированием.Как использовать синтаксический анализатор xml для чтения и записи большого xml?
sample.xml
<ROOT>
<test src="http://dfs.com">Hi</test>
<project1>This is old data<foo></foo></project1>
<bar>
<project1>ty</project1>
<foo></foo>
</bar>
</ROOT>
Вот моя попытка ..
parser.py
from xml.sax.handler import ContentHandler
import xml.sax
class MyHandler(xml.sax.handler.ContentHandler):
def __init__(self, out_file):
self._charBuffer = []
self._result = []
self._out = open(out_file, 'w')
def _createElement(self, name, attrs):
attributes = attrs.items()
if attributes:
out = ''
for key, value in attributes:
out += ' {}={}'.format(key, value)
return '<{}{}>'.format(name, out)
return '<{}>'.format(name)
def _getCharacterData(self):
data = ''.join(self._charBuffer).strip()
self._charBuffer = []
self._out.write(data.strip()) #remove strip() if whitespace is important
def parse(self, f):
xml.sax.parse(f, self)
def characters(self, data):
self._charBuffer.append(data)
def startElement(self, name, attrs):
if not name == 'project1':
self._result.append({})
self._out.write(self._createElement(name, attrs))
def endElement(self, name):
if not name == 'project1': self._result[-1][name] = self._getCharacterData()
MyHandler('out.xml').parse("sample.xml")
Я не могу заставить его работать.
В чем проблема обработки данных в виде текста? Просто: отметьте флаг, он опущен, возьмите линию, это проект1, поднимите флаг, напишите/добавьте или нет, повторите ... Только схема стратегии – ar7max
Но этот подход приведет к загрузке всего файла в память. –
Я имею в виду: read line - строка процесса - состояние обновления - выберите запись или нет. Не работайте со всем файлом сразу. Нет нужды. – ar7max