1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import re
20 import sys
21
22
24
25 """
26 XML writer, UTF-8 aware
27 """
28
29
30
31
32 _re = re.compile("(&|<|>|'|\"|[^\x09\x0a\x0d\x20-\xFF])")
33 _escaped_chars = {
34 '&': '&',
35 '<': '<',
36 '>': '>',
37 '"': '"',
38 "'": ''',
39 }
40
41 - def __init__(self, stream=sys.stdout, skip_xml_decl=0):
42 self.tag_stack = []
43 self.stream = stream
44 if not skip_xml_decl:
45 self.stream.write('<?xml version="1.0" encoding="UTF-8"?>')
46
47 - def open_tag(self, name, attributes=None, namespace=None):
51
52 - def empty_tag(self, name, attributes=None, namespace=None):
56
57
58 - def _open_tag(self, empty, name, attributes=None, namespace=None):
77
79 """
80 Closes a previously open tag.
81 This function raises an exception if the tag was not opened before, or
82 if it's been closed already.
83 """
84 if not self.tag_stack:
85 raise Exception("Could not close tag %s: empty tag stack" % name)
86 if namespace:
87 name = "%s:%s" % (namespace, name)
88
89 if self.tag_stack[-1] != name:
90 raise Exception("Could not close tag %s if not opened before" \
91 % name)
92 self.tag_stack.pop()
93
94 self.stream.write("</")
95 self.data(name)
96 self.stream.write(">")
97
98 - def data(self, data_string):
99 """
100 Writes the data, performing the necessary UTF-8 conversions
101 max_bytes is the satellite schema dependent maximum value (in bytes)
102 which can fit in the matching table row. Yeah, this is very gross.
103 """
104 if data_string is None:
105 data_string = ""
106 else:
107 data_string = str(data_string)
108
109 data_string = self._re.sub(self._sub_function, data_string)
110 self.stream.write(data_string)
111
112
113
114
121
124
125 if __name__ == '__main__':
126 weirdtag = chr(248) + 'gootag'
127 writer = XMLWriter()
128 writer.open_tag(weirdtag)
129 writer.open_tag("message")
130 writer.open_tag("text", attributes={'from': 'Trond Eivind Glomsrød', 'to': "Bernhard Rosenkr)Bänzer"})
131 writer.data("String with \"quotes\", 'apostroph', Trond Eivind Glomsrød\n and Bernhard Rosenkr)Bänzer")
132 r = re.compile("(&|<|>|'|\"|[^\x09\x0a\x0d\x20-\xFF])")
133 writer.close_tag("text")
134 writer.close_tag("message")
135 writer.empty_tag("yahoo", attributes={'abc': 1})
136 writer.close_tag(weirdtag)
137 print("")
138