Migrated from ElementTree to lxml. #176
This commit is contained in:
parent
15358326da
commit
63fdde230d
9 changed files with 296 additions and 281 deletions
|
|
@ -7,7 +7,8 @@ import re
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
import xml.etree.cElementTree as ET
|
|
||||||
|
import lxml.etree as ET
|
||||||
|
|
||||||
if sys.hexversion < 0x02070000:
|
if sys.hexversion < 0x02070000:
|
||||||
# pylint: disable=F0401,E0611
|
# pylint: disable=F0401,E0611
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"""Core definitions to be shared amongst the modules.
|
"""Core definitions to be shared amongst the modules.
|
||||||
"""
|
"""
|
||||||
import copy
|
import copy
|
||||||
import xml.etree.cElementTree as ET
|
import lxml.etree as ET
|
||||||
|
|
||||||
# Progression order
|
# Progression order
|
||||||
LRCP = 0
|
LRCP = 0
|
||||||
|
|
@ -81,9 +81,9 @@ _CAPABILITIES_DISPLAY = {
|
||||||
def _pretty_print_xml(xml, level=0):
|
def _pretty_print_xml(xml, level=0):
|
||||||
"""Pretty print XML data.
|
"""Pretty print XML data.
|
||||||
"""
|
"""
|
||||||
xml = copy.deepcopy(xml)
|
#xml = copy.deepcopy(xml)
|
||||||
_indent(xml.getroot(), level=level)
|
#_indent(xml.getroot(), level=level)
|
||||||
xmltext = ET.tostring(xml.getroot(), encoding='utf-8').decode('utf-8')
|
xmltext = ET.tostring(xml, encoding='utf-8').decode('utf-8')
|
||||||
|
|
||||||
# Indent it a bit.
|
# Indent it a bit.
|
||||||
lst = [(' ' + x) for x in xmltext.split('\n')]
|
lst = [(' ' + x) for x in xmltext.split('\n')]
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ import struct
|
||||||
import sys
|
import sys
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
import xml.etree.cElementTree as ET
|
|
||||||
|
|
||||||
|
import lxml.etree as ET
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from .codestream import Codestream
|
from .codestream import Codestream
|
||||||
|
|
@ -2565,7 +2565,10 @@ class XMLBox(Jp2kBox):
|
||||||
|
|
||||||
xml = self.xml
|
xml = self.xml
|
||||||
if self.xml is not None:
|
if self.xml is not None:
|
||||||
msg += _pretty_print_xml(self.xml)
|
bstr = ET.tostring(self.xml,
|
||||||
|
encoding='utf-8',
|
||||||
|
pretty_print=True).decode('utf-8')
|
||||||
|
msg += '\n {0}'.format(bstr)
|
||||||
else:
|
else:
|
||||||
msg += '\n {0}'.format(xml)
|
msg += '\n {0}'.format(xml)
|
||||||
return msg
|
return msg
|
||||||
|
|
@ -2971,8 +2974,10 @@ class UUIDBox(Jp2kBox):
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
if self.uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
if self.uuid == uuid.UUID('be7acfcb-97a9-42e8-9c71-999491e3afac'):
|
||||||
line = '\n UUID Data: {0}'
|
line = '\n UUID Data:\n{0}'
|
||||||
xmlstring = _pretty_print_xml(self.data)
|
xmlstring = ET.tostring(self.data,
|
||||||
|
encoding='utf-8',
|
||||||
|
pretty_print=True).decode('utf-8')
|
||||||
xmlstring = xmlstring.rstrip()
|
xmlstring = xmlstring.rstrip()
|
||||||
msg += line.format(xmlstring)
|
msg += line.format(xmlstring)
|
||||||
elif self.uuid.bytes == b'JpgTiffExif->JP2':
|
elif self.uuid.bytes == b'JpgTiffExif->JP2':
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,8 @@ def read_pgx_header(pgx_file):
|
||||||
nemo_xmp_box = """UUID Box (uuid) @ (77, 3146)
|
nemo_xmp_box = """UUID Box (uuid) @ (77, 3146)
|
||||||
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
||||||
UUID Data:
|
UUID Data:
|
||||||
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2">
|
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
|
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
<rdf:Description rdf:about="">
|
<rdf:Description rdf:about="">
|
||||||
<ns2:CreatorTool>Google</ns2:CreatorTool>
|
<ns2:CreatorTool>Google</ns2:CreatorTool>
|
||||||
|
|
@ -266,7 +267,8 @@ nemo_xmp_box = """UUID Box (uuid) @ (77, 3146)
|
||||||
</dc:Creator>
|
</dc:Creator>
|
||||||
</rdf:Description>
|
</rdf:Description>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</ns0:xmpmeta>"""
|
</ns0:xmpmeta>
|
||||||
|
<?xpacket end="w"?>"""
|
||||||
|
|
||||||
SimpleRDF = """<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
|
SimpleRDF = """<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
|
||||||
<rdf:Description rdf:about='Test:XMPCoreCoverage/kSimpleRDF'
|
<rdf:Description rdf:about='Test:XMPCoreCoverage/kSimpleRDF'
|
||||||
|
|
@ -372,7 +374,8 @@ JP2 Header Box (jp2h) @ (32, 45)
|
||||||
UUID Box (uuid) @ (77, 3146)
|
UUID Box (uuid) @ (77, 3146)
|
||||||
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
||||||
UUID Data:
|
UUID Data:
|
||||||
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2">
|
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
|
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
<rdf:Description rdf:about="">
|
<rdf:Description rdf:about="">
|
||||||
<ns2:CreatorTool>Google</ns2:CreatorTool>
|
<ns2:CreatorTool>Google</ns2:CreatorTool>
|
||||||
|
|
@ -454,7 +457,8 @@ UUID Box (uuid) @ (77, 3146)
|
||||||
</dc:Creator>
|
</dc:Creator>
|
||||||
</rdf:Description>
|
</rdf:Description>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</ns0:xmpmeta>
|
</ns0:xmpmeta>
|
||||||
|
<?xpacket end="w"?>
|
||||||
Contiguous Codestream Box (jp2c) @ (3223, 1132296)
|
Contiguous Codestream Box (jp2c) @ (3223, 1132296)
|
||||||
Main header:
|
Main header:
|
||||||
SOC marker segment @ (3231, 0)
|
SOC marker segment @ (3231, 0)
|
||||||
|
|
@ -576,7 +580,8 @@ JP2 Header Box (jp2h) @ (32, 45)
|
||||||
UUID Box (uuid) @ (77, 3146)
|
UUID Box (uuid) @ (77, 3146)
|
||||||
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
||||||
UUID Data:
|
UUID Data:
|
||||||
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2">
|
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
|
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2">
|
||||||
<rdf:RDF>
|
<rdf:RDF>
|
||||||
<rdf:Description rdf:about="">
|
<rdf:Description rdf:about="">
|
||||||
<ns2:CreatorTool>Google</ns2:CreatorTool>
|
<ns2:CreatorTool>Google</ns2:CreatorTool>
|
||||||
|
|
@ -658,7 +663,8 @@ UUID Box (uuid) @ (77, 3146)
|
||||||
</dc:Creator>
|
</dc:Creator>
|
||||||
</rdf:Description>
|
</rdf:Description>
|
||||||
</rdf:RDF>
|
</rdf:RDF>
|
||||||
</ns0:xmpmeta>
|
</ns0:xmpmeta>
|
||||||
|
<?xpacket end="w"?>
|
||||||
Contiguous Codestream Box (jp2c) @ (3223, 1132296)"""
|
Contiguous Codestream Box (jp2c) @ (3223, 1132296)"""
|
||||||
|
|
||||||
nemo_dump_no_codestream_no_xml = r"""JPEG 2000 Signature Box (jP ) @ (0, 12)
|
nemo_dump_no_codestream_no_xml = r"""JPEG 2000 Signature Box (jP ) @ (0, 12)
|
||||||
|
|
@ -691,10 +697,10 @@ file7_rreq = r"""Reader Requirements Box (rreq) @ (44, 24)
|
||||||
Feature 043: 0x40 Deprecated - compositing layer uses restricted ICC profile
|
Feature 043: 0x40 Deprecated - compositing layer uses restricted ICC profile
|
||||||
Vendor Features:"""
|
Vendor Features:"""
|
||||||
|
|
||||||
file1_xml = r"""XML Box (xml ) @ (36, 439)
|
file1_xml = """XML Box (xml ) @ (36, 439)
|
||||||
<ns0:IMAGE_CREATION xmlns:ns0="http://www.jpeg.org/jpx/1.0/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jpeg.org/jpx/1.0/xml http://www.jpeg.org/metadata/15444-2.xsd">
|
<IMAGE_CREATION xmlns="http://www.jpeg.org/jpx/1.0/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jpeg.org/jpx/1.0/xml http://www.jpeg.org/metadata/15444-2.xsd">
|
||||||
<ns0:GENERAL_CREATION_INFO>
|
\t<GENERAL_CREATION_INFO>
|
||||||
<ns0:CREATION_TIME>2001-11-01T13:45:00.000-06:00</ns0:CREATION_TIME>
|
\t\t<CREATION_TIME>2001-11-01T13:45:00.000-06:00</CREATION_TIME>
|
||||||
<ns0:IMAGE_SOURCE>Professional 120 Image</ns0:IMAGE_SOURCE>
|
\t\t<IMAGE_SOURCE>Professional 120 Image</IMAGE_SOURCE>
|
||||||
</ns0:GENERAL_CREATION_INFO>
|
\t</GENERAL_CREATION_INFO>
|
||||||
</ns0:IMAGE_CREATION>"""
|
</IMAGE_CREATION>"""
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,10 @@ import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import uuid
|
import uuid
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
import xml.etree.cElementTree as ET
|
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
import lxml.etree as ET
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
|
|
@ -1056,7 +1056,7 @@ class TestRepr(unittest.TestCase):
|
||||||
box = glymur.jp2box.XMLBox(xml=tree)
|
box = glymur.jp2box.XMLBox(xml=tree)
|
||||||
|
|
||||||
regexp = r"""glymur.jp2box.XMLBox"""
|
regexp = r"""glymur.jp2box.XMLBox"""
|
||||||
regexp += r"""\(xml=<(xml.etree.ElementTree.){0,1}ElementTree object """
|
regexp += r"""\(xml=<lxml.etree._ElementTree object """
|
||||||
regexp += """at 0x([a-f0-9]*)>\)"""
|
regexp += """at 0x([a-f0-9]*)>\)"""
|
||||||
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
import xml.etree.cElementTree as ET
|
import lxml.etree as ET
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
import xml.etree
|
|
||||||
|
|
||||||
if sys.hexversion < 0x02070000:
|
if sys.hexversion < 0x02070000:
|
||||||
import unittest2 as unittest
|
import unittest2 as unittest
|
||||||
|
|
@ -35,6 +34,8 @@ if sys.hexversion <= 0x03030000:
|
||||||
else:
|
else:
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import lxml.etree
|
||||||
|
|
||||||
from .fixtures import HAS_PYTHON_XMP_TOOLKIT, OPJ_DATA_ROOT
|
from .fixtures import HAS_PYTHON_XMP_TOOLKIT, OPJ_DATA_ROOT
|
||||||
if HAS_PYTHON_XMP_TOOLKIT:
|
if HAS_PYTHON_XMP_TOOLKIT:
|
||||||
from libxmp import XMPMeta
|
from libxmp import XMPMeta
|
||||||
|
|
@ -71,7 +72,7 @@ class TestUUIDXMP(unittest.TestCase):
|
||||||
# The data should be an XMP packet, which gets interpreted as
|
# The data should be an XMP packet, which gets interpreted as
|
||||||
# an ElementTree.
|
# an ElementTree.
|
||||||
self.assertTrue(isinstance(jp2.box[-1].data,
|
self.assertTrue(isinstance(jp2.box[-1].data,
|
||||||
xml.etree.ElementTree.ElementTree))
|
lxml.etree._ElementTree))
|
||||||
|
|
||||||
class TestUUIDExif(unittest.TestCase):
|
class TestUUIDExif(unittest.TestCase):
|
||||||
"""Tests for UUIDs of Exif type."""
|
"""Tests for UUIDs of Exif type."""
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
import warnings
|
||||||
import xml.etree.cElementTree as ET
|
|
||||||
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
@ -32,6 +31,8 @@ if sys.hexversion <= 0x03030000:
|
||||||
else:
|
else:
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import lxml.etree as ET
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
from glymur.jp2box import ColourSpecificationBox, ContiguousCodestreamBox
|
from glymur.jp2box import ColourSpecificationBox, ContiguousCodestreamBox
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import warnings
|
import warnings
|
||||||
from xml.etree import cElementTree as ET
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
|
|
@ -28,10 +27,12 @@ if sys.hexversion <= 0x03030000:
|
||||||
else:
|
else:
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import lxml.etree as ET
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
from . import fixtures
|
from . import fixtures
|
||||||
from .fixtures import OPJ_DATA_ROOT, opj_data_file, nemo_xmp_box
|
from .fixtures import OPJ_DATA_ROOT, opj_data_file
|
||||||
from .fixtures import text_gbr_27, text_gbr_33, text_gbr_34
|
from .fixtures import text_gbr_27, text_gbr_33, text_gbr_34
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -118,6 +119,7 @@ class TestPrinting(unittest.TestCase):
|
||||||
lst = actual.split('\n')
|
lst = actual.split('\n')
|
||||||
lst = lst[1:]
|
lst = lst[1:]
|
||||||
actual = '\n'.join(lst)
|
actual = '\n'.join(lst)
|
||||||
|
self.maxDiff = None
|
||||||
self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
|
self.assertEqual(actual, fixtures.nemo_dump_no_codestream)
|
||||||
|
|
||||||
def test_printoptions_no_xml(self):
|
def test_printoptions_no_xml(self):
|
||||||
|
|
@ -209,6 +211,7 @@ class TestPrinting(unittest.TestCase):
|
||||||
lst = actual.split('\n')
|
lst = actual.split('\n')
|
||||||
lst = lst[1:]
|
lst = lst[1:]
|
||||||
actual = '\n'.join(lst)
|
actual = '\n'.join(lst)
|
||||||
|
self.maxDiff = None
|
||||||
self.assertEqual(actual, fixtures.nemo_dump_full)
|
self.assertEqual(actual, fixtures.nemo_dump_full)
|
||||||
|
|
||||||
def test_entire_file(self):
|
def test_entire_file(self):
|
||||||
|
|
@ -567,7 +570,7 @@ class TestPrinting(unittest.TestCase):
|
||||||
print(j.box[3])
|
print(j.box[3])
|
||||||
actual = fake_out.getvalue().strip()
|
actual = fake_out.getvalue().strip()
|
||||||
|
|
||||||
expected = nemo_xmp_box
|
expected = fixtures.nemo_xmp_box
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
def test_codestream(self):
|
def test_codestream(self):
|
||||||
|
|
@ -639,8 +642,7 @@ class TestPrinting(unittest.TestCase):
|
||||||
#
|
#
|
||||||
# 2.7.5 (fedora 19) prints xml entities.
|
# 2.7.5 (fedora 19) prints xml entities.
|
||||||
# 2.7.3 seems to want to print hex escapes.
|
# 2.7.3 seems to want to print hex escapes.
|
||||||
text = u"""<?xml version="1.0" encoding="utf-8"?>
|
text = u"""<flow>Strömung</flow>"""
|
||||||
<flow>Strömung</flow>"""
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
xml = ET.parse(StringIO(text.encode('utf-8')))
|
xml = ET.parse(StringIO(text.encode('utf-8')))
|
||||||
else:
|
else:
|
||||||
|
|
@ -668,8 +670,7 @@ class TestPrinting(unittest.TestCase):
|
||||||
#
|
#
|
||||||
# 2.7.5 (fedora 19) prints xml entities.
|
# 2.7.5 (fedora 19) prints xml entities.
|
||||||
# 2.7.3 seems to want to print hex escapes.
|
# 2.7.3 seems to want to print hex escapes.
|
||||||
text = u"""<?xml version="1.0" encoding="utf-8"?>
|
text = u"""<country>Россия</country>"""
|
||||||
<country>Россия</country>"""
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
xml = ET.parse(StringIO(text.encode('utf-8')))
|
xml = ET.parse(StringIO(text.encode('utf-8')))
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue