/
xmlutils.py
84 lines (62 loc) · 2.12 KB
/
xmlutils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# -*- coding: utf-8 -*-
#
# This file is part of DataCite.
#
# Copyright (C) 2016 CERN.
#
# DataCite is free software; you can redistribute it and/or modify it
# under the terms of the Revised BSD License; see LICENSE file for
# more details.
"""XML utilities."""
from __future__ import absolute_import, print_function
from collections import OrderedDict
from lxml import etree
def dump_etree_helper(data, rules, nsmap, attrib):
"""Convert DataCite JSON format to DataCite XML.
JSON should be validated before it is given to to_xml.
"""
output = etree.Element('resource', nsmap=nsmap, attrib=attrib)
for rule in rules:
if rule not in data:
continue
element = rules[rule](rule, data[rule])
if element is not None:
output.append(element)
return output
def etree_to_string(root, pretty_print=True, xml_declaration=True,
encoding='utf-8'):
"""Dump XML etree as a string."""
return etree.tostring(
root,
pretty_print=pretty_print,
xml_declaration=xml_declaration,
encoding=encoding,
).decode('utf-8')
def set_elem_attr(element, attrib, data):
"""Set a tag for an XML element if the value is not empty."""
if attrib in data and data[attrib]:
element.set(attrib, data[attrib])
def set_non_empty_attr(element, attribute, value):
"""Set a tag for an XML element if the value is not empty."""
if value:
element.set(attribute, value)
class Rules(object):
"""Rules container."""
def __init__(self):
"""Initialize rules object."""
self.rules = OrderedDict()
def __getitem__(self, key):
"""Get rule for key."""
return self.rules[key]
def __iter__(self):
"""Get iterator for rules."""
return iter(self.rules)
def rule(self, key):
"""Decorate as a rule for a key in top level JSON."""
def register(f):
if key in self.rules:
raise ValueError(
'Rule for "{0}" already registered'.format(key))
self.rules[key] = f
return f
return register