Skip to content

Commit 8d3d32e

Browse files
authored
Merge pull request #207 from OpenDataServices/198-test-lxml
Require lxml
2 parents 7fa9693 + 4513cd3 commit 8d3d32e

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ python:
66
- "3.4"
77
- "3.5"
88
# Apparently six must be installed first, otherwise setup.py will be unhappy
9-
install: pip install six && pip install --upgrade -r requirements_dev.txt
9+
install:
10+
- pip install six
11+
- pip install --upgrade -r requirements_dev.txt
1012
script: py.test --cov .
1113
after_success: coveralls

examples/iati/expected.xml

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,57 @@
1-
<iati-activities><!--XML generated by flatten-tool--><iati-activity><iati-identifier>AA-AAA-123456789-ABC123</iati-identifier><reporting-org ref="AA-AAA-123456789" type="40"><narrative>Organisation name</narrative></reporting-org><participating-org ref="AA-AAA-123456789" role="1" /><activity-status code="2" /><activity-date iso-date="2011-10-01" type="1" /><recipient-country code="AF" percentage="40" /><recipient-country code="XK" percentage="60" /><title><narrative>A title</narrative></title><description><narrative>A description</narrative></description><transaction><transaction-type code="2" /><transaction-date iso-date="2012-01-01" /><value value-date="2012-01-01">10</value></transaction><transaction><transaction-type code="3" /><transaction-date iso-date="2012-03-03" /><value value-date="2012-03-03">20</value></transaction></iati-activity><iati-activity><iati-identifier>AA-AAA-123456789-ABC124</iati-identifier><reporting-org ref="AA-AAA-123456789" type="40"><narrative>Organisation name</narrative></reporting-org><participating-org ref="AA-AAA-123456789" role="1" /><activity-status code="3" /><activity-date iso-date="2016-01-01" type="2" /><recipient-country code="AG" percentage="30" /><recipient-country code="XK" percentage="70" /><title><narrative>Another title</narrative></title><description><narrative>Another description</narrative></description><transaction><transaction-type code="2" /><transaction-date iso-date="2013-04-04" /><value value-date="2013-04-04">30</value></transaction><transaction><transaction-type code="3" /><transaction-date iso-date="2013-05-05" /><value value-date="2013-05-05">40</value></transaction></iati-activity></iati-activities>
1+
<iati-activities>
2+
<!--XML generated by flatten-tool-->
3+
<iati-activity>
4+
<iati-identifier>AA-AAA-123456789-ABC123</iati-identifier>
5+
<reporting-org ref="AA-AAA-123456789" type="40">
6+
<narrative>Organisation name</narrative>
7+
</reporting-org>
8+
<participating-org ref="AA-AAA-123456789" role="1"/>
9+
<activity-status code="2"/>
10+
<activity-date iso-date="2011-10-01" type="1"/>
11+
<recipient-country code="AF" percentage="40"/>
12+
<recipient-country code="XK" percentage="60"/>
13+
<title>
14+
<narrative>A title</narrative>
15+
</title>
16+
<description>
17+
<narrative>A description</narrative>
18+
</description>
19+
<transaction>
20+
<transaction-type code="2"/>
21+
<transaction-date iso-date="2012-01-01"/>
22+
<value value-date="2012-01-01">10</value>
23+
</transaction>
24+
<transaction>
25+
<transaction-type code="3"/>
26+
<transaction-date iso-date="2012-03-03"/>
27+
<value value-date="2012-03-03">20</value>
28+
</transaction>
29+
</iati-activity>
30+
<iati-activity>
31+
<iati-identifier>AA-AAA-123456789-ABC124</iati-identifier>
32+
<reporting-org ref="AA-AAA-123456789" type="40">
33+
<narrative>Organisation name</narrative>
34+
</reporting-org>
35+
<participating-org ref="AA-AAA-123456789" role="1"/>
36+
<activity-status code="3"/>
37+
<activity-date iso-date="2016-01-01" type="2"/>
38+
<recipient-country code="AG" percentage="30"/>
39+
<recipient-country code="XK" percentage="70"/>
40+
<title>
41+
<narrative>Another title</narrative>
42+
</title>
43+
<description>
44+
<narrative>Another description</narrative>
45+
</description>
46+
<transaction>
47+
<transaction-type code="2"/>
48+
<transaction-date iso-date="2013-04-04"/>
49+
<value value-date="2013-04-04">30</value>
50+
</transaction>
51+
<transaction>
52+
<transaction-type code="3"/>
53+
<transaction-date iso-date="2013-05-05"/>
54+
<value value-date="2013-05-05">40</value>
55+
</transaction>
56+
</iati-activity>
57+
</iati-activities>
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
<iati-organisations><!--XML generated by flatten-tool--><iati-organisation><organisation-identifier>AA-AAA-123456789</organisation-identifier><reporting-org ref="AA-AAA-123456789" secondary-reporter="0" type="40" /></iati-organisation></iati-organisations>
1+
<iati-organisations>
2+
<!--XML generated by flatten-tool-->
3+
<iati-organisation>
4+
<organisation-identifier>AA-AAA-123456789</organisation-identifier>
5+
<reporting-org ref="AA-AAA-123456789" secondary-reporter="0" type="40"/>
6+
</iati-organisation>
7+
</iati-organisations>

flattentool/xml_output.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
from collections import OrderedDict
2+
from warnings import warn
13
try:
24
import lxml.etree as ET
35
# If we're using lxml we have to do some extra work to support namespaces,
46
# so we have a variable to check whether we're using lxml:
57
USING_LXML = True
8+
# Note that lxml is now "required" - it's listed as a requirement in
9+
# setup.py and is needed for the tests to pass.
10+
# However, stdlib etree still exists as an unsupported feature.
611
except ImportError:
712
import xml.etree.ElementTree as ET
813
USING_LXML = False
9-
from warnings import warn
14+
warn('Using stdlib etree may work, but is not supported. Please install lxml.')
1015
from flattentool.exceptions import DataErrorWarning
1116

1217

18+
def sort_attributes(data):
19+
attribs = []
20+
other = []
21+
for k, v in data.items():
22+
(other, attribs)[k.startswith('@')].append((k, v))
23+
return OrderedDict(sorted(attribs) + other)
24+
25+
1326
def child_to_xml(parent_el, tagname, child, toplevel=False, nsmap=None):
1427
if hasattr(child, 'items'):
1528
child_el = dict_to_xml(child, tagname, toplevel=False, nsmap=nsmap)
@@ -45,6 +58,9 @@ def dict_to_xml(data, tagname, toplevel=True, nsmap=None):
4558
warn(str(e), DataErrorWarning)
4659
return
4760

61+
if USING_LXML:
62+
data = sort_attributes(data)
63+
4864
for k, v in data.items():
4965
if type(v) == list:
5066
for item in v:
@@ -62,4 +78,8 @@ def toxml(data, xml_root_tag):
6278
root = dict_to_xml(data, xml_root_tag, nsmap=nsmap)
6379
comment = ET.Comment('XML generated by flatten-tool')
6480
root.insert(0, comment)
65-
return ET.tostring(root)
81+
if USING_LXML:
82+
return ET.tostring(root, pretty_print=True)
83+
else:
84+
indent(root)
85+
return ET.tostring(root)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from setuptools import setup
22
import sys
33

4-
install_requires = ['jsonref', 'schema', 'openpyxl>=2.5', 'six', 'pytz', 'xmltodict']
4+
install_requires = ['jsonref', 'schema', 'openpyxl>=2.5', 'six', 'pytz', 'xmltodict', 'lxml']
55

66
if sys.version < '3':
77
install_requires.append('unicodecsv')

0 commit comments

Comments
 (0)