Package pyx12 :: Module xmlwriter
[hide private]

Source Code for Module pyx12.xmlwriter

  1  # A simple XML-generator# Originally Lars Marius Garshol, September 1998 
  2  # http://mail.python.org/pipermail/xml-sig/1998-September/000347.html 
  3  # Changes by Uche Ogbuji April 2003 
  4  # *  unicode support: accept encoding argument and use Python codecs 
  5  #    for correct character output 
  6  # *  switch from deprecated string module to string methods 
  7  # *  use PEP 8 style 
  8   
  9  import sys 
 10  import codecs 
 11   
12 -class XMLWriter(object):
13 """ 14 Doctest: 15 16 >>>from xmlwriter import XMLWriter 17 >>>writer = XMLWriter() 18 >>>writer.doctype( 19 ... u"xsa", u"-//LM Garshol//DTD XML Software Autoupdate 1.0//EN//XML", 20 ... u"http://www.garshol.priv.no/download/xsa/xsa.dtd") 21 >>>#Notice: there is no error checking to ensure that the root element 22 >>>#specified in the doctype matches the top-level element generated 23 >>>writer.push(u"xsa") 24 >>>#Another element with child elements 25 >>>writer.push(u"vendor") 26 >>>#Element with simple text (#PCDATA) content 27 >>>writer.elem(u"name", u"Centigrade systems") 28 >>>writer.elem(u"email", u"info@centigrade.bogus") 29 >>>writer.elem(u"vendor", u"Centigrade systems") 30 >>>#Close currently open element ("vendor) 31 >>>writer.pop() 32 >>>#Element with an attribute 33 >>>writer.push(u"product", {u"id": u"100\u00B0"}) 34 >>>writer.elem(u"name", u"100\u00B0 Server") 35 >>>writer.elem(u"version", u"1.0") 36 >>>writer.elem(u"last-release", u"20030401") 37 >>>#Empty element 38 >>>writer.empty(u"changes") 39 >>>writer.pop() 40 >>>writer.pop() 41 42 startElement 43 endElement 44 emptyElement 45 text, data 46 endDocument 47 attribute 48 indentation 49 close 50 flush 51 """ 52
53 - def __init__(self, out=sys.stdout, encoding="utf-8", indent=u" "):
54 """ 55 out - a stream for the output 56 encoding - an encoding used to wrap the output for unicode 57 indent - white space used for indentation 58 """ 59 wrapper = codecs.lookup(encoding)[3] 60 self.out = wrapper(out) 61 self.stack = [] 62 self.indent = indent 63 self.out.write(u'<?xml version="1.0" encoding="%s"?>\n' % encoding)
64
65 - def doctype(self, root, pubid, sysid):
66 """ 67 Create a document type declaration (no internal subset) 68 """ 69 if pubid == None: 70 self.out.write( 71 u"<!DOCTYPE %s SYSTEM '%s'>\n" % (root, sysid)) 72 else: 73 self.out.write( 74 u"<!DOCTYPE %s PUBLIC '%s' '%s'>\n" \ 75 % (root, pubid, sysid))
76
77 - def push(self, elem, attrs={}):
78 """ 79 Create an element which will have child elements 80 """ 81 self._indent() 82 self.out.write("<" + elem) 83 for (a, v) in attrs.items(): 84 self.out.write(u" %s='%s'" % (a, self._escape_attr(v))) 85 self.out.write(u">\n") 86 self.stack.append(elem)
87
88 - def elem(self, elem, content, attrs={}):
89 """ 90 Create an element with text content only 91 """ 92 self._indent() 93 self.out.write(u"<" + elem) 94 for (a, v) in attrs.items(): 95 self.out.write(u" %s='%s'" % (a, self._escape_attr(v))) 96 self.out.write(u">%s</%s>\n" \ 97 % (self._escape_cont(content), elem))
98
99 - def empty(self, elem, attrs={}):
100 """ 101 Create an empty element 102 """ 103 self._indent() 104 self.out.write(u"<"+elem) 105 for a in attrs.items(): 106 self.out.write(u" %s='%s'" % a) 107 self.out.write(u"/>\n")
108
109 - def pop(self):
110 """ 111 Close an element started with the push() method 112 """ 113 if len(self.stack) > 0: 114 elem=self.stack[-1] 115 del self.stack[-1] 116 self._indent() 117 self.out.write(u"</%s>\n" % elem)
118
119 - def __len__(self):
120 return len(self.stack)
121
122 - def _indent(self):
123 self.out.write(self.indent * (len(self.stack) * 2))
124
125 - def _escape_cont(self, text):
126 if text is None: 127 return None 128 return text.replace(u"&", u"&amp;")\ 129 .replace(u"<", u"&lt;").replace(u">", u"&gt;")
130
131 - def _escape_attr(self, text):
132 if text is None: 133 return None 134 return text.replace(u"&", u"&amp;") \ 135 .replace(u"'", u"&apos;").replace(u"<", u"&lt;")\ 136 .replace(u">", u"&gt;")
137