diff --git a/scrapy/trunk/scrapy/tests/test_xpath.py b/scrapy/trunk/scrapy/tests/test_xpath.py
index 9b1efb2be..3a8e6dd78 100644
--- a/scrapy/trunk/scrapy/tests/test_xpath.py
+++ b/scrapy/trunk/scrapy/tests/test_xpath.py
@@ -26,7 +26,7 @@ class XPathTestCase(unittest.TestCase):
xl = xpath.x('//input')
self.assertEqual(2, len(xl))
for x in xl:
- assert isinstance(x, XPathSelector)
+ assert isinstance(x, HtmlXPathSelector)
self.assertEqual(xpath.x('//input').extract(),
[x.extract() for x in xpath.x('//input')])
@@ -41,6 +41,26 @@ class XPathTestCase(unittest.TestCase):
self.assertEqual([x.extract() for x in xpath.x("concat(//input[@name='a']/@value, //input[@name='b']/@value)")],
[u'12'])
+ def test_selector_same_type(self):
+ """Test XPathSelector returning the same type in x() method"""
+ text = '
test
'
+ assert isinstance(XmlXPathSelector(text=text).x("//p")[0],
+ XmlXPathSelector)
+ assert isinstance(HtmlXPathSelector(text=text).x("//p")[0],
+ HtmlXPathSelector)
+
+ def test_selector_xml_html(self):
+ """Test that XML and HTML XPathSelector's behave differently"""
+
+ # some text which is parsed differently by XML and HTML flavors
+ text = '

Hello
'
+
+ self.assertEqual(XmlXPathSelector(text=text).x("//div").extract(),
+ [u'
Hello
'])
+
+ self.assertEqual(HtmlXPathSelector(text=text).x("//div").extract(),
+ [u'
Hello
'])
+
def test_selector_nested(self):
"""Nested selector tests"""
body = """
diff --git a/scrapy/trunk/scrapy/xpath/selector.py b/scrapy/trunk/scrapy/xpath/selector.py
index 70e007457..566ed53d5 100644
--- a/scrapy/trunk/scrapy/xpath/selector.py
+++ b/scrapy/trunk/scrapy/xpath/selector.py
@@ -39,10 +39,11 @@ class XPathSelector(object):
if hasattr(self.xmlNode, 'xpathEval'):
self.doc.xpathContext.setContextNode(self.xmlNode)
xpath_result = self.doc.xpathContext.xpathEval(xpath)
+ cls = type(self)
if hasattr(xpath_result, '__iter__'):
- return XPathSelectorList([XPathSelector(node=node, parent=self, expr=xpath) for node in xpath_result])
+ return XPathSelectorList([cls(node=node, parent=self, expr=xpath) for node in xpath_result])
else:
- return XPathSelectorList([XPathSelector(node=xpath_result, parent=self, expr=xpath)])
+ return XPathSelectorList([cls(node=xpath_result, parent=self, expr=xpath)])
else:
return XPathSelectorList([])
@@ -77,7 +78,7 @@ class XPathSelector(object):
self.doc.xpathContext.xpathRegisterNs(prefix, uri)
def __str__(self):
- return "" % (getattr(self.xmlNode, 'name'), self.expr)
+ return "<%s (%s) xpath=%s>" % (type(self).__name__, getattr(self.xmlNode, 'name'), self.expr)
__repr__ = __str__
@@ -100,12 +101,15 @@ class XPathSelectorList(list):
XPathSelector of the list"""
return [x.extract() if isinstance(x, XPathSelector) else x for x in self]
+
class XmlXPathSelector(XPathSelector):
"""XPathSelector for XML content"""
- def __init__(self, response=None, text=None):
- XPathSelector.__init__(self, response=response, text=text, constructor=xmlDoc_from_xml)
+ def __init__(self, *args, **kwargs):
+ kwargs['constructor'] = xmlDoc_from_xml
+ XPathSelector.__init__(self, *args, **kwargs)
class HtmlXPathSelector(XPathSelector):
"""XPathSelector for HTML content"""
- def __init__(self, response=None, text=None):
- XPathSelector.__init__(self, response=response, text=text, constructor=xmlDoc_from_html)
+ def __init__(self, *args, **kwargs):
+ kwargs['constructor'] = xmlDoc_from_html
+ XPathSelector.__init__(self, *args, **kwargs)