diff --git a/docs/topics/exporters.rst b/docs/topics/exporters.rst index 15458dddc..ceba04e6a 100644 --- a/docs/topics/exporters.rst +++ b/docs/topics/exporters.rst @@ -240,6 +240,26 @@ XmlItemExporter + Unless overriden in :meth:`serialize_field` method, multi-valued fields are + exported by serializing each value inside a ```` element. This is for + convenience, as multi-valued fields are very common. + + For example, the item:: + + Item(name=['John', 'Doe'], age='23') + + Would be serialized as:: + + + + + + John + Doe + + 23 + + CsvItemExporter --------------- diff --git a/scrapy/contrib/exporter/__init__.py b/scrapy/contrib/exporter/__init__.py index c230e6822..90ad47cc5 100644 --- a/scrapy/contrib/exporter/__init__.py +++ b/scrapy/contrib/exporter/__init__.py @@ -95,7 +95,11 @@ class XmlItemExporter(BaseItemExporter): def _export_xml_field(self, name, serialized_value): self.xg.startElement(name, {}) - self.xg.characters(serialized_value) + if hasattr(serialized_value, '__iter__'): + for value in serialized_value: + self._export_xml_field('value', value) + else: + self.xg.characters(serialized_value) self.xg.endElement(name) diff --git a/scrapy/tests/test_contrib_exporter.py b/scrapy/tests/test_contrib_exporter.py index 9b91759c9..48cc90c46 100644 --- a/scrapy/tests/test_contrib_exporter.py +++ b/scrapy/tests/test_contrib_exporter.py @@ -137,6 +137,15 @@ class XmlItemExporterTest(BaseItemExporterTest): expected_value = '\n22John\xc2\xa3' self.assertEqual(self.output.getvalue(), expected_value) + def test_multivalued_fields(self): + output = StringIO() + item = TestItem(name=[u'John\xa3', u'Doe']) + ie = XmlItemExporter(output) + ie.start_exporting() + ie.export_item(item) + ie.finish_exporting() + expected_value = '\nJohn\xc2\xa3Doe' + self.assertEqual(output.getvalue(), expected_value) class JsonLinesItemExporterTest(BaseItemExporterTest):