Package backend :: Package satellite_tools :: Package exporter :: Module xmlWriter
[hide private]
[frames] | no frames]

Source Code for Module backend.satellite_tools.exporter.xmlWriter

  1  # -*- coding: ISO-8859-1 -*- 
  2  # 
  3  # Copyright (c) 2008--2016 Red Hat, Inc. 
  4  # 
  5  # This software is licensed to you under the GNU General Public License, 
  6  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  7  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  8  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  9  # along with this software; if not, see 
 10  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 11  # 
 12  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 13  # granted to use or replicate Red Hat trademarks that are incorporated 
 14  # in this software or its documentation. 
 15  # 
 16  # UTF-8 aware XML writer 
 17  # 
 18   
 19  import re 
 20  import sys 
 21   
 22   
23 -class XMLWriter:
24 25 """ 26 XML writer, UTF-8 aware 27 """ 28 29 # We escape &<>'" and chars UTF-8 does not properly escape (everything 30 # other than tab (\x09), newline and carriage return (\x0a and \x0d) and 31 # stuff above ASCII 32) 32 _re = re.compile("(&|<|>|'|\"|[^\x09\x0a\x0d\x20-\xFF])") 33 _escaped_chars = { 34 '&': '&amp;', 35 '<': '&lt;', 36 '>': '&gt;', 37 '"': '&quot;', 38 "'": '&apos;', 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):
48 "Opens a tag with the specified attributes" 49 return self._open_tag(None, name, attributes=attributes, 50 namespace=namespace)
51
52 - def empty_tag(self, name, attributes=None, namespace=None):
53 "Writes an empty tag with the specified attributes" 54 return self._open_tag(1, name, attributes=attributes, 55 namespace=namespace)
56 57 # Now the function that does most of the work for open_tag and empty_tag
58 - def _open_tag(self, empty, name, attributes=None, namespace=None):
59 if namespace: 60 name = "%s:%s" % (namespace, name) 61 self.stream.write("<") 62 self.data(name) 63 # Dump the attributes, if any 64 if attributes: 65 for k, v in attributes.items(): 66 self.stream.write(" ") 67 self.data(k) 68 self.stream.write('="') 69 self.data(str(v)) 70 self.stream.write('"') 71 if empty: 72 self.stream.write("/") 73 self.stream.write(">") 74 75 if not empty: 76 self.tag_stack.append(name)
77
78 - def close_tag(self, name, namespace=None):
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 # Helper functions 113 114 # Substitution function for re
115 - def _sub_function(self, match_object):
116 c = match_object.group() 117 if c in self._escaped_chars: 118 return self._escaped_chars[c] 119 # return "&#%d;" % ord(c) 120 return '?'
121
122 - def flush(self):
123 self.stream.flush()
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