I'm trying to remove all the project1
nodes (along with their child elements) from the below sample xml document (original document is about 30 GB) using SAX parser.It would be fine to have a separate modified file or ok with the in-line edit.
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>
Here is my attempt..
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")
I can't make it to work.
elementtree.iterparse
is easier to use, and allows good control over the objects created by the parser. – Slivovitz