Skip to content

Instantly share code, notes, and snippets.

@cscorley
Created June 25, 2012 01:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cscorley/2985855 to your computer and use it in GitHub Desktop.
Save cscorley/2985855 to your computer and use it in GitHub Desktop.
lxml RangedTarget for hacking in ranged sourceline numbers
from lxml import etree
class RangedTarget(etree.TreeBuilder):
"""
Extends the regular etree.TreeBuilder target to assign all elements
built two attributes:
ranged_tag_start = line number of the start tag
ranged_tag_end = line number of the end tag
To use this, you must feed the parser line by line, while assigning
the current line number to this object.
Example use:
with open('test.xml') as f:
lines = f.readlines()
parser = etree.XMLParser(target=RangedTarget())
for i in range(len(lines)):
parser.target.current_line = i
parser.feed(lines[i])
root = parser.close()
for event, element in etree.iterwalk(root):
print("%s, %s, %s" % (event, element.tag, element.attrib))
"""
def __init__(self, element_factory=None, parser=None):
super(RangedTarget, self).__init__(element_factory=element_factory,
parser=parser)
self.current_line = None
@property
def current_line(self):
return self._line
@current_line.setter
def current_line(self, line):
self._line = line
def end(self, tag):
element = super(RangedTarget, self).end(tag)
element.set('ranged_tag_start', str(element.sourceline))
element.set('ranged_tag_end', str(self.current_line))
return element
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment