summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2013-09-13 21:21:37 +0200
committerStefan Behnel <stefan_ml@behnel.de>2013-09-13 21:21:37 +0200
commitce6f80be65d791a358187a00f0192ca3bdce83c3 (patch)
tree15359c2bcd13f693bd133bc2c7315143ec6f9537 /src
parente72660d3bca3bfb83118d15f13388e135982fd1e (diff)
downloadpython-lxml-ce6f80be65d791a358187a00f0192ca3bdce83c3.tar.gz
fix event collection with custom targets, write some tests for it and add an example to the documentation
Diffstat (limited to 'src')
-rw-r--r--src/lxml/parser.pxi15
-rw-r--r--src/lxml/tests/test_etree.py117
2 files changed, 125 insertions, 7 deletions
diff --git a/src/lxml/parser.pxi b/src/lxml/parser.pxi
index 3e1cd8cf..285b7469 100644
--- a/src/lxml/parser.pxi
+++ b/src/lxml/parser.pxi
@@ -827,18 +827,19 @@ cdef class _BaseParser:
return self._push_parser_context
cdef _ParserContext _createContext(self, target, events_to_collect):
- cdef _TargetParserContext target_context
cdef _SaxParserContext sax_context
if target is not None:
- target_context = _TargetParserContext()
- target_context._setTarget(target)
- return target_context
+ sax_context = _TargetParserContext()
+ (<_TargetParserContext>sax_context)._setTarget(target)
+ elif events_to_collect:
+ sax_context = _SaxParserContext()
+ else:
+ # nothing special to configure
+ return _ParserContext()
if events_to_collect:
events, tag = events_to_collect
- sax_context = _SaxParserContext()
sax_context._setEventFilter(events, tag)
- return sax_context
- return _ParserContext()
+ return sax_context
cdef int _registerHtmlErrorHandler(self, xmlparser.xmlParserCtxt* c_ctxt) except -1:
cdef xmlparser.xmlSAXHandler* sax = c_ctxt.sax
diff --git a/src/lxml/tests/test_etree.py b/src/lxml/tests/test_etree.py
index c1896fdb..704a53a6 100644
--- a/src/lxml/tests/test_etree.py
+++ b/src/lxml/tests/test_etree.py
@@ -3770,6 +3770,122 @@ class ETreeErrorLogTest(HelperTestCase):
self.assertTrue([ message for message in messages
if ':1:15:' in message ])
+
+class XMLPullParserTest(unittest.TestCase):
+ etree = etree
+
+ def assert_event_tags(self, events, expected):
+ self.assertEqual([(action, elem.tag) for action, elem in events],
+ expected)
+
+ def test_pull_from_simple_target(self):
+ class Target(object):
+ def start(self, tag, attrib):
+ return 'start(%s)' % tag
+ def end(self, tag):
+ return 'end(%s)' % tag
+ def close(self):
+ return 'close()'
+
+ parser = self.etree.XMLPullParser(target=Target())
+ events = parser.read_events()
+
+ parser.feed('<root><element>')
+ self.assertFalse(list(events))
+ self.assertFalse(list(events))
+ parser.feed('</element><child>')
+ self.assertEqual([('end', 'end(element)')], list(events))
+ parser.feed('</child>')
+ self.assertEqual([('end', 'end(child)')], list(events))
+ parser.feed('</root>')
+ self.assertEqual([('end', 'end(root)')], list(events))
+ self.assertFalse(list(events))
+ self.assertEqual('close()', parser.close())
+
+ def test_pull_from_simple_target_start_end(self):
+ class Target(object):
+ def start(self, tag, attrib):
+ return 'start(%s)' % tag
+ def end(self, tag):
+ return 'end(%s)' % tag
+ def close(self):
+ return 'close()'
+
+ parser = self.etree.XMLPullParser(
+ ['start', 'end'], target=Target())
+ events = parser.read_events()
+
+ parser.feed('<root><element>')
+ self.assertEqual(
+ [('start', 'start(root)'), ('start', 'start(element)')],
+ list(events))
+ self.assertFalse(list(events))
+ parser.feed('</element><child>')
+ self.assertEqual(
+ [('end', 'end(element)'), ('start', 'start(child)')],
+ list(events))
+ parser.feed('</child>')
+ self.assertEqual(
+ [('end', 'end(child)')],
+ list(events))
+ parser.feed('</root>')
+ self.assertEqual(
+ [('end', 'end(root)')],
+ list(events))
+ self.assertFalse(list(events))
+ self.assertEqual('close()', parser.close())
+
+ def test_pull_from_tree_builder(self):
+ parser = self.etree.XMLPullParser(
+ ['start', 'end'], target=etree.TreeBuilder())
+ events = parser.read_events()
+
+ parser.feed('<root><element>')
+ self.assert_event_tags(
+ events, [('start', 'root'), ('start', 'element')])
+ self.assertFalse(list(events))
+ parser.feed('</element><child>')
+ self.assert_event_tags(
+ events, [('end', 'element'), ('start', 'child')])
+ parser.feed('</child>')
+ self.assert_event_tags(
+ events, [('end', 'child')])
+ parser.feed('</root>')
+ self.assert_event_tags(
+ events, [('end', 'root')])
+ self.assertFalse(list(events))
+ root = parser.close()
+ self.assertEqual('root', root.tag)
+
+ def test_pull_from_tree_builder_subclass(self):
+ class Target(etree.TreeBuilder):
+ def end(self, tag):
+ el = super(Target, self).end(tag)
+ el.tag += '-huhu'
+ return el
+
+ parser = self.etree.XMLPullParser(
+ ['start', 'end'], target=Target())
+ events = parser.read_events()
+
+ parser.feed('<root><element>')
+ self.assert_event_tags(
+ events, [('start', 'root'), ('start', 'element')])
+ self.assertFalse(list(events))
+ parser.feed('</element><child>')
+ self.assert_event_tags(
+ events, [('end', 'element-huhu'), ('start', 'child')])
+ parser.feed('</child>')
+ self.assert_event_tags(
+ events, [('end', 'child-huhu')])
+ parser.feed('</root>')
+ self.assert_event_tags(
+ events, [('end', 'root-huhu')])
+ self.assertFalse(list(events))
+ root = parser.close()
+ self.assertEqual('root-huhu', root.tag)
+
+
def test_suite():
suite = unittest.TestSuite()
suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
@@ -3778,6 +3894,7 @@ def test_suite():
suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
+ suite.addTests([unittest.makeSuite(XMLPullParserTest)])
suite.addTests(
[make_doctest('../../../doc/tutorial.txt')])
if sys.version_info >= (2,6):