]>
git.proxmox.com Git - mirror_edk2.git/blob - AppPkg/Applications/Python/Python-2.7.10/Lib/xml/sax/saxutils.py
674df6d74d75733b93b1bdb578baa298a22865d7
2 A library of useful helper classes to the SAX classes, for the
3 convenience of application and driver writers.
6 import os
, urlparse
, urllib
, types
13 _StringTypes
= [types
.StringType
, types
.UnicodeType
]
14 except AttributeError:
15 _StringTypes
= [types
.StringType
]
17 def __dict_replace(s
, d
):
18 """Replace substrings of a string using a dictionary."""
19 for key
, value
in d
.items():
20 s
= s
.replace(key
, value
)
23 def escape(data
, entities
={}):
24 """Escape &, <, and > in a string of data.
26 You can escape other strings of data by passing a dictionary as
27 the optional entities parameter. The keys and values must all be
28 strings; each key will be replaced with its corresponding value.
31 # must do ampersand first
32 data
= data
.replace("&", "&")
33 data
= data
.replace(">", ">")
34 data
= data
.replace("<", "<")
36 data
= __dict_replace(data
, entities
)
39 def unescape(data
, entities
={}):
40 """Unescape &, <, and > in a string of data.
42 You can unescape other strings of data by passing a dictionary as
43 the optional entities parameter. The keys and values must all be
44 strings; each key will be replaced with its corresponding value.
46 data
= data
.replace("<", "<")
47 data
= data
.replace(">", ">")
49 data
= __dict_replace(data
, entities
)
50 # must do ampersand last
51 return data
.replace("&", "&")
53 def quoteattr(data
, entities
={}):
54 """Escape and quote an attribute value.
56 Escape &, <, and > in a string of data, then quote it for use as
57 an attribute value. The \" character will be escaped as well, if
60 You can escape other strings of data by passing a dictionary as
61 the optional entities parameter. The keys and values must all be
62 strings; each key will be replaced with its corresponding value.
64 entities
= entities
.copy()
65 entities
.update({'\n': ' ', '\r': ' ', '\t':'	'})
66 data
= escape(data
, entities
)
69 data
= '"%s"' % data
.replace('"', """)
77 def _gettextwriter(out
, encoding
):
82 if isinstance(out
, io
.RawIOBase
):
83 buffer = io
.BufferedIOBase(out
)
84 # Keep the original file open when the TextIOWrapper is
86 buffer.close
= lambda: None
88 # This is to handle passed objects that aren't in the
89 # IOBase hierarchy, but just have a write method
90 buffer = io
.BufferedIOBase()
91 buffer.writable
= lambda: True
92 buffer.write
= out
.write
94 # TextIOWrapper uses this methods to determine
95 # if BOM (for UTF-16, etc) should be added
96 buffer.seekable
= out
.seekable
97 buffer.tell
= out
.tell
98 except AttributeError:
100 # wrap a binary writer with TextIOWrapper
101 return _UnbufferedTextIOWrapper(buffer, encoding
=encoding
,
102 errors
='xmlcharrefreplace',
106 class _UnbufferedTextIOWrapper(io
.TextIOWrapper
):
108 super(_UnbufferedTextIOWrapper
, self
).write(s
)
112 class XMLGenerator(handler
.ContentHandler
):
114 def __init__(self
, out
=None, encoding
="iso-8859-1"):
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
124 def _qname(self
, name
):
125 """Builds a qualified name from a (ns_url, localname) pair"""
127 # Per http://www.w3.org/XML/1998/namespace, The 'xml' prefix is
128 # bound by definition to http://www.w3.org/XML/1998/namespace. It
129 # does not need to be declared and will not usually be found in
130 # self._current_context.
131 if 'http://www.w3.org/XML/1998/namespace' == name
[0]:
132 return 'xml:' + name
[1]
133 # The name is in a non-empty namespace
134 prefix
= self
._current
_context
[name
[0]]
136 # If it is not the default namespace, prepend the prefix
137 return prefix
+ ":" + name
[1]
138 # Return the unqualified name
141 # ContentHandler methods
143 def startDocument(self
):
144 self
._write
(u
'<?xml version="1.0" encoding="%s"?>\n' %
147 def endDocument(self
):
150 def startPrefixMapping(self
, prefix
, uri
):
151 self
._ns
_contexts
.append(self
._current
_context
.copy())
152 self
._current
_context
[uri
] = prefix
153 self
._undeclared
_ns
_maps
.append((prefix
, uri
))
155 def endPrefixMapping(self
, prefix
):
156 self
._current
_context
= self
._ns
_contexts
[-1]
157 del self
._ns
_contexts
[-1]
159 def startElement(self
, name
, attrs
):
160 self
._write
(u
'<' + name
)
161 for (name
, value
) in attrs
.items():
162 self
._write
(u
' %s=%s' % (name
, quoteattr(value
)))
165 def endElement(self
, name
):
166 self
._write
(u
'</%s>' % name
)
168 def startElementNS(self
, name
, qname
, attrs
):
169 self
._write
(u
'<' + self
._qname
(name
))
171 for prefix
, uri
in self
._undeclared
_ns
_maps
:
173 self
._write
(u
' xmlns:%s="%s"' % (prefix
, uri
))
175 self
._write
(u
' xmlns="%s"' % uri
)
176 self
._undeclared
_ns
_maps
= []
178 for (name
, value
) in attrs
.items():
179 self
._write
(u
' %s=%s' % (self
._qname
(name
), quoteattr(value
)))
182 def endElementNS(self
, name
, qname
):
183 self
._write
(u
'</%s>' % self
._qname
(name
))
185 def characters(self
, content
):
186 if not isinstance(content
, unicode):
187 content
= unicode(content
, self
._encoding
)
188 self
._write
(escape(content
))
190 def ignorableWhitespace(self
, content
):
191 if not isinstance(content
, unicode):
192 content
= unicode(content
, self
._encoding
)
195 def processingInstruction(self
, target
, data
):
196 self
._write
(u
'<?%s %s?>' % (target
, data
))
199 class XMLFilterBase(xmlreader
.XMLReader
):
200 """This class is designed to sit between an XMLReader and the
201 client application's event handlers. By default, it does nothing
202 but pass requests up to the reader and events on to the handlers
203 unmodified, but subclasses can override specific methods to modify
204 the event stream or the configuration requests as they pass
207 def __init__(self
, parent
= None):
208 xmlreader
.XMLReader
.__init
__(self
)
209 self
._parent
= parent
211 # ErrorHandler methods
213 def error(self
, exception
):
214 self
._err
_handler
.error(exception
)
216 def fatalError(self
, exception
):
217 self
._err
_handler
.fatalError(exception
)
219 def warning(self
, exception
):
220 self
._err
_handler
.warning(exception
)
222 # ContentHandler methods
224 def setDocumentLocator(self
, locator
):
225 self
._cont
_handler
.setDocumentLocator(locator
)
227 def startDocument(self
):
228 self
._cont
_handler
.startDocument()
230 def endDocument(self
):
231 self
._cont
_handler
.endDocument()
233 def startPrefixMapping(self
, prefix
, uri
):
234 self
._cont
_handler
.startPrefixMapping(prefix
, uri
)
236 def endPrefixMapping(self
, prefix
):
237 self
._cont
_handler
.endPrefixMapping(prefix
)
239 def startElement(self
, name
, attrs
):
240 self
._cont
_handler
.startElement(name
, attrs
)
242 def endElement(self
, name
):
243 self
._cont
_handler
.endElement(name
)
245 def startElementNS(self
, name
, qname
, attrs
):
246 self
._cont
_handler
.startElementNS(name
, qname
, attrs
)
248 def endElementNS(self
, name
, qname
):
249 self
._cont
_handler
.endElementNS(name
, qname
)
251 def characters(self
, content
):
252 self
._cont
_handler
.characters(content
)
254 def ignorableWhitespace(self
, chars
):
255 self
._cont
_handler
.ignorableWhitespace(chars
)
257 def processingInstruction(self
, target
, data
):
258 self
._cont
_handler
.processingInstruction(target
, data
)
260 def skippedEntity(self
, name
):
261 self
._cont
_handler
.skippedEntity(name
)
265 def notationDecl(self
, name
, publicId
, systemId
):
266 self
._dtd
_handler
.notationDecl(name
, publicId
, systemId
)
268 def unparsedEntityDecl(self
, name
, publicId
, systemId
, ndata
):
269 self
._dtd
_handler
.unparsedEntityDecl(name
, publicId
, systemId
, ndata
)
271 # EntityResolver methods
273 def resolveEntity(self
, publicId
, systemId
):
274 return self
._ent
_handler
.resolveEntity(publicId
, systemId
)
278 def parse(self
, source
):
279 self
._parent
.setContentHandler(self
)
280 self
._parent
.setErrorHandler(self
)
281 self
._parent
.setEntityResolver(self
)
282 self
._parent
.setDTDHandler(self
)
283 self
._parent
.parse(source
)
285 def setLocale(self
, locale
):
286 self
._parent
.setLocale(locale
)
288 def getFeature(self
, name
):
289 return self
._parent
.getFeature(name
)
291 def setFeature(self
, name
, state
):
292 self
._parent
.setFeature(name
, state
)
294 def getProperty(self
, name
):
295 return self
._parent
.getProperty(name
)
297 def setProperty(self
, name
, value
):
298 self
._parent
.setProperty(name
, value
)
305 def setParent(self
, parent
):
306 self
._parent
= parent
308 # --- Utility functions
310 def prepare_input_source(source
, base
= ""):
311 """This function takes an InputSource and an optional base URL and
312 returns a fully resolved InputSource object ready for reading."""
314 if type(source
) in _StringTypes
:
315 source
= xmlreader
.InputSource(source
)
316 elif hasattr(source
, "read"):
318 source
= xmlreader
.InputSource()
319 source
.setByteStream(f
)
320 if hasattr(f
, "name"):
321 source
.setSystemId(f
.name
)
323 if source
.getByteStream() is None:
325 sysid
= source
.getSystemId()
326 basehead
= os
.path
.dirname(os
.path
.normpath(base
))
327 encoding
= sys
.getfilesystemencoding()
328 if isinstance(sysid
, unicode):
329 if not isinstance(basehead
, unicode):
331 basehead
= basehead
.decode(encoding
)
332 except UnicodeDecodeError:
333 sysid
= sysid
.encode(encoding
)
335 if isinstance(basehead
, unicode):
337 sysid
= sysid
.decode(encoding
)
338 except UnicodeDecodeError:
339 basehead
= basehead
.encode(encoding
)
340 sysidfilename
= os
.path
.join(basehead
, sysid
)
341 isfile
= os
.path
.isfile(sysidfilename
)
345 source
.setSystemId(sysidfilename
)
346 f
= open(sysidfilename
, "rb")
348 source
.setSystemId(urlparse
.urljoin(base
, source
.getSystemId()))
349 f
= urllib
.urlopen(source
.getSystemId())
351 source
.setByteStream(f
)