| 110 | write_through=True) |
| 111 | |
| 112 | class XMLGenerator(handler.ContentHandler): |
| 113 | |
| 114 | def __init__(self, out=None, encoding="iso-8859-1", short_empty_elements=False): |
| 115 | handler.ContentHandler.__init__(self) |
| 116 | out = _gettextwriter(out, encoding) |
| 117 | self._write = out.write |
| 118 | self._flush = out.flush |
| 119 | self._ns_contexts = [{}] # contains uri -> prefix dicts |
| 120 | self._current_context = self._ns_contexts[-1] |
| 121 | self._undeclared_ns_maps = [] |
| 122 | self._encoding = encoding |
| 123 | self._short_empty_elements = short_empty_elements |
| 124 | self._pending_start_element = False |
| 125 | |
| 126 | def _qname(self, name): |
| 127 | """Builds a qualified name from a (ns_url, localname) pair""" |
| 128 | if name[0]: |
| 129 | # Per http://www.w3.org/XML/1998/namespace, The 'xml' prefix is |
| 130 | # bound by definition to http://www.w3.org/XML/1998/namespace. It |
| 131 | # does not need to be declared and will not usually be found in |
| 132 | # self._current_context. |
| 133 | if 'http://www.w3.org/XML/1998/namespace' == name[0]: |
| 134 | return 'xml:' + name[1] |
| 135 | # The name is in a non-empty namespace |
| 136 | prefix = self._current_context[name[0]] |
| 137 | if prefix: |
| 138 | # If it is not the default namespace, prepend the prefix |
| 139 | return prefix + ":" + name[1] |
| 140 | # Return the unqualified name |
| 141 | return name[1] |
| 142 | |
| 143 | def _finish_pending_start_element(self,endElement=False): |
| 144 | if self._pending_start_element: |
| 145 | self._write('>') |
| 146 | self._pending_start_element = False |
| 147 | |
| 148 | # ContentHandler methods |
| 149 | |
| 150 | def startDocument(self): |
| 151 | self._write('<?xml version="1.0" encoding="%s"?>\n' % |
| 152 | self._encoding) |
| 153 | |
| 154 | def endDocument(self): |
| 155 | self._flush() |
| 156 | |
| 157 | def startPrefixMapping(self, prefix, uri): |
| 158 | self._ns_contexts.append(self._current_context.copy()) |
| 159 | self._current_context[uri] = prefix |
| 160 | self._undeclared_ns_maps.append((prefix, uri)) |
| 161 | |
| 162 | def endPrefixMapping(self, prefix): |
| 163 | self._current_context = self._ns_contexts[-1] |
| 164 | del self._ns_contexts[-1] |
| 165 | |
| 166 | def startElement(self, name, attrs): |
| 167 | self._finish_pending_start_element() |
| 168 | self._write('<' + name) |
| 169 | for (name, value) in attrs.items(): |
no outgoing calls
searching dependent graphs…