From 82d138e87e68b1e198dfdc3b0d7f62d0de2e1ceb Mon Sep 17 00:00:00 2001 From: tpeng Date: Mon, 1 Dec 2014 14:15:15 +0100 Subject: [PATCH] support namespace prefix in xmliter_lxml --- scrapy/contrib_exp/iterators.py | 6 +++--- tests/test_utils_iterators.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/scrapy/contrib_exp/iterators.py b/scrapy/contrib_exp/iterators.py index 7cf9103fd..d96105fb9 100644 --- a/scrapy/contrib_exp/iterators.py +++ b/scrapy/contrib_exp/iterators.py @@ -2,18 +2,18 @@ from scrapy.http import Response from scrapy.selector import Selector -def xmliter_lxml(obj, nodename, namespace=None): +def xmliter_lxml(obj, nodename, namespace=None, prefix='x'): from lxml import etree reader = _StreamReader(obj) tag = '{%s}%s' % (namespace, nodename) if namespace else nodename iterable = etree.iterparse(reader, tag=tag, encoding=reader.encoding) - selxpath = '//' + ('x:%s' % nodename if namespace else nodename) + selxpath = '//' + ('%s:%s' % (prefix, nodename) if namespace else nodename) for _, node in iterable: nodetext = etree.tostring(node) node.clear() xs = Selector(text=nodetext, type='xml') if namespace: - xs.register_namespace('x', namespace) + xs.register_namespace(prefix, namespace) yield xs.xpath(selxpath)[0] diff --git a/tests/test_utils_iterators.py b/tests/test_utils_iterators.py index 840f4c596..d8faa810c 100644 --- a/tests/test_utils_iterators.py +++ b/tests/test_utils_iterators.py @@ -124,6 +124,38 @@ class LxmlXmliterTestCase(XmliterTestCase): node = next(namespace_iter) self.assertEqual(node.xpath('text()').extract(), ['http://www.mydummycompany.com/images/item2.jpg']) + def test_xmliter_namespaces_prefix(self): + body = """\ + + + + + Apples + Bananas + + + + + African Coffee Table + 80 + 120 + + + + """ + response = XmlResponse(url='http://mydummycompany.com', body=body) + my_iter = self.xmliter(response, 'table', 'http://www.w3.org/TR/html4/', 'h') + + node = next(my_iter) + self.assertEqual(len(node.xpath('h:tr/h:td').extract()), 2) + self.assertEqual(node.xpath('h:tr/h:td[1]/text()').extract(), ['Apples']) + self.assertEqual(node.xpath('h:tr/h:td[2]/text()').extract(), ['Bananas']) + + my_iter = self.xmliter(response, 'table', 'http://www.w3schools.com/furniture', 'f') + + node = next(my_iter) + self.assertEqual(node.xpath('f:name/text()').extract(), ['African Coffee Table']) + class UtilsCsvTestCase(unittest.TestCase): sample_feeds_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'sample_data', 'feeds')