diff --git a/glymur/jp2box.py b/glymur/jp2box.py index f213cab..bf88e4d 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -2747,9 +2747,18 @@ def _pretty_print_xml(xml, level=0): """ xml = copy.deepcopy(xml) _indent(xml.getroot(), level=level) - xmltext = ET.tostring(xml.getroot()).decode('utf-8') + xmltext = ET.tostring(xml.getroot(), encoding='utf-8').decode('utf-8') # Indent it a bit. lst = [(' ' + x) for x in xmltext.split('\n')] - xml = '\n'.join(lst) - return '\n{0}'.format(xml) + try: + xml = '\n'.join(lst) + return '\n{0}'.format(xml) + except UnicodeEncodeError: + # This can happen on python 2.x if the character set contains certain + # non-ascii characters. Just print out the corresponding xml char + # entities instead. + xml = u'\n'.join(lst) + text = u'\n{0}'.format(xml) + text = text.encode('ascii', 'xmlcharrefreplace') + return text diff --git a/glymur/test/test_jp2box_xml.py b/glymur/test/test_jp2box_xml.py index 7e6980f..b875188 100644 --- a/glymur/test/test_jp2box_xml.py +++ b/glymur/test/test_jp2box_xml.py @@ -148,54 +148,26 @@ class TestXML(unittest.TestCase): self.assertEqual(neighbor.attrib['name'], 'Malaysia') self.assertEqual(neighbor.attrib['direction'], 'N') - -@unittest.skipIf(os.name == "nt", "Temporary file issue on window.") -class TestUTF8XML(unittest.TestCase): - """Test suite for UTF-8 XML boxes.""" - - def setUp(self): - """Create a JP2 file with a UTF-8 XML box.""" - self.j2kfile = glymur.data.goodstuff() - - # 'Россия' is 'Russia' in Cyrillic, not that it matters. - - xml = u""" - Россия""" - with tempfile.NamedTemporaryFile(suffix=".xml", delete=False) as tfile: - tfile.write(xml.encode('utf-8')) - tfile.flush() - self.xmlfile = tfile.name - - j2k = glymur.Jp2k(self.j2kfile) - with tempfile.NamedTemporaryFile(suffix=".jp2", delete=False) as tfile: - jp2 = j2k.wrap(tfile.name) - xmlbox = glymur.jp2box.XMLBox(filename=self.xmlfile) - jp2.append(xmlbox) - self.jp2_xml_file = tfile.name - - def tearDown(self): - os.unlink(self.xmlfile) - os.unlink(self.jp2_xml_file) - def test_utf8_xml(self): """Should be able to write/read an XMLBox with utf-8 encoding.""" - jp2 = Jp2k(self.jp2_xml_file) - box_xml = jp2.box[-1].xml.getroot() - box_xml_str = ET.tostring(box_xml, encoding='utf-8').decode('utf-8') - self.assertEqual(box_xml_str, - u'Россия') + # 'Россия' is 'Russia' in Cyrillic, not that it matters. + xml = u""" + Россия""" + with tempfile.NamedTemporaryFile(suffix=".xml") as xmlfile: + xmlfile.write(xml.encode('utf-8')) + xmlfile.flush() - @unittest.skip("Does not print properly.") - def test_printing_utf8_xml(self): - """Should be able to print an XMLBox with utf-8 encoding.""" - jp2 = Jp2k(self.jp2_xml_file) - with patch('sys.stdout', new=StringIO()) as fake_out: - print(jp2.box[-1]) - actual = fake_out.getvalue().strip() - lines = ["XML Box (xml ) @ (115305, 39)", - " u'Россия'"] - expected = '\n'.join(lines) - self.assertEqual(actual, expected) + j2k = glymur.Jp2k(self.j2kfile) + with tempfile.NamedTemporaryFile(suffix=".jp2") as jfile: + jp2 = j2k.wrap(jfile.name) + xmlbox = glymur.jp2box.XMLBox(filename=xmlfile.name) + jp2.append(xmlbox) + + box_xml = jp2.box[-1].xml.getroot() + box_xml_str = ET.tostring(box_xml, + encoding='utf-8').decode('utf-8') + self.assertEqual(box_xml_str, + u'Россия') diff --git a/glymur/test/test_printing.py b/glymur/test/test_printing.py index 2694aa2..ef2b7f2 100644 --- a/glymur/test/test_printing.py +++ b/glymur/test/test_printing.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """Test suite for printing. """ # C0302: don't care too much about having too many lines in a test module @@ -15,6 +16,7 @@ import struct import sys import tempfile import warnings +from xml.etree import cElementTree as ET if sys.hexversion < 0x02070000: import unittest2 as unittest @@ -730,6 +732,46 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) + @unittest.skipIf(sys.hexversion < 0x02070000, + "Differences in XML printing between 2.6 and 2.7") + def test_xml_latin1(self): + """Should be able to print an XMLBox with utf-8 encoding (latin1).""" + text = u""" + Strömung""" + if sys.hexversion < 0x03000000: + xml = ET.parse(StringIO(text.encode('utf-8'))) + else: + xml = ET.parse(StringIO(text)) + + xmlbox = glymur.jp2box.XMLBox(xml=xml) + with patch('sys.stdout', new=StringIO()) as fake_out: + print(xmlbox) + actual = fake_out.getvalue().strip() + lines = ["XML Box (xml ) @ (-1, 0)", + " Strömung"] + expected = '\n'.join(lines) + self.assertEqual(actual, expected) + + @unittest.skipIf(sys.hexversion < 0x02070000, + "Differences in XML printing between 2.6 and 2.7") + def test_xml_cyrrilic(self): + """Should be able to print an XMLBox with utf-8 encoding (cyrrillic).""" + text = u""" + Россия""" + if sys.hexversion < 0x03000000: + xml = ET.parse(StringIO(text.encode('utf-8'))) + else: + xml = ET.parse(StringIO(text)) + + xmlbox = glymur.jp2box.XMLBox(xml=xml) + with patch('sys.stdout', new=StringIO()) as fake_out: + print(xmlbox) + actual = fake_out.getvalue().strip() + lines = ["XML Box (xml ) @ (-1, 0)", + " Россия"] + expected = '\n'.join(lines) + self.assertEqual(actual, expected) + @unittest.skipIf(OPJ_DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_channel_definition(self):