def _escape_cdata(text, encoding=None, replace=string.replace): try: if encoding: text = _encode(text, encoding) text = replace(text, "&", "&") text = replace(text, "<", "<") text = replace(text, ">", ">") return text except (TypeError, AttributeError): _raise_serialization_error(text)
def _escape_cdata(text): try: if str.startswith(text, "<![CDATA[") and str.endswith(text, "]]>"): return text if "&" in text: text = text.replace("&", "&") if "<" in text: text = text.replace("<", "<") if ">" in text: text = text.replace(">", ">") return text except (TypeError, AttributeError): _raise_serialization_error(text)
def _escape_attrib(attr_val, encoding=None, replace=string.replace): # escape attribute value text = str(attr_val) try: if encoding: text = _encode(text, encoding) text = replace(text, "&", "&") #text = replace(text, "'", "'") # FIXME: overkill text = replace(text, "\"", """) text = replace(text, "<", "<") text = replace(text, ">", ">") return text except (TypeError, AttributeError): _raise_serialization_error(text)
def _escape_cdata(text): # escape character data try: # it's worth avoiding do-nothing calls for strings that are # shorter than 500 character, or so. assume that's, by far, # the most common case in most applications. if "&" in text: text = text.replace("&", "&") if "<" in text: text = text.replace("<", "<") if ">" in text: text = text.replace(">", ">") if "'" in text: text = text.replace("'", "'") if '"' in text: text = text.replace('"', """) return text except (TypeError, AttributeError): _raise_serialization_error(text)
def _prettywrite(self, file, node, encoding, namespaces, depth=0): # write XML to file tag = node.tag if tag is Comment: file.write("\r\n" + " " * depth) file.write("<!-- %s -->" % _escape_cdata(node.text, encoding)) elif tag is ProcessingInstruction: file.write("\r\n" + " " * depth) file.write("<?%s?>" % _escape_cdata(node.text, encoding)) else: items = node.items() xmlns_items = [] # new namespaces in this scope try: if isinstance(tag, QName) or tag[:1] == "{": tag, xmlns = myfixtag(tag, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(tag) file.write("\r\n" + " " * depth) file.write("<" + _encode(tag, encoding)) if items or xmlns_items: items.sort() # lexical order for k, v in items: try: if isinstance(k, QName) or k[:1] == "{": k, xmlns = myfixtag(k, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(k) try: if isinstance(v, QName): v, xmlns = myfixtag(v, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(v) file.write(" %s=\"%s\"" % (_encode(k, encoding), _escape_attrib(v, encoding))) for k, v in xmlns_items: file.write(" %s=\"%s\"" % (_encode(k, encoding), _escape_attrib(v, encoding))) if node.text or len(node): file.write(">") if node.text: file.write(_escape_cdata(node.text, encoding)) for n in node: self._prettywrite(file, n, encoding, namespaces, depth=depth + 1) if not node.text or len(node): file.write("\r\n" + " " * depth) file.write("</" + _encode(tag, encoding) + ">") else: file.write(" />") for k, v in xmlns_items: del namespaces[v] if node.tail: file.write(_escape_cdata(node.tail, encoding))
def _write(self, file, node, encoding, namespaces): # write XML to file tag = node.tag if tag is Comment: file.write("\n<!-- %s -->" % _escape_cdata(node.text, encoding)) elif tag is ProcessingInstruction: file.write("\n<?%s?>" % _escape_cdata(node.text, encoding)) else: items = node.items() xmlns_items = [] # new namespaces in this scope try: if isinstance(tag, QName) or tag[:1] == "{": tag, xmlns = fixtag(tag, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(tag) file.write("\n<" + _encode(tag, encoding)) if items or xmlns_items: items.sort() # lexical order for k, v in items: try: if isinstance(k, QName) or k[:1] == "{": k, xmlns = fixtag(k, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(k) try: if isinstance(v, QName): v, xmlns = fixtag(v, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(v) file.write( " %s=\"%s\"" % (_encode(k, encoding), _escape_attrib(v, encoding))) for k, v in xmlns_items: file.write( " %s=\"%s\"" % (_encode(k, encoding), _escape_attrib(v, encoding))) if node.text or len(node): file.write(">") if node.text: file.write(_escape_cdata(node.text, encoding)) for n in node: self._write(file, n, encoding, namespaces) file.write("</" + _encode(tag, encoding) + ">") else: file.write(" />") for k, v in xmlns_items: del namespaces[v] if node.tail: file.write(_escape_cdata(node.tail, encoding))
def _print_node(self, node, encoding): tree_string = "" tag = node.tag if tag is Comment: tree_string += "<!-- %s -->" % _escape_cdata(node.text, encoding) elif tag is ProcessingInstruction: tree_string += "<?%s?>" % _escape_cdata(node.text, encoding) else: items = node.items() xmlns_items = [] # new namespaces in this scope try: if isinstance(tag, QName) or tag[:1] == "{": tag, xmlns = fixtag(tag, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(tag) tree_string += "<" + _encode(tag, encoding) if items or xmlns_items: items.sort() # lexical order for k, v in items: try: if isinstance(k, QName) or k[:1] == "{": k, xmlns = fixtag(k, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(k) try: if isinstance(v, QName): v, xmlns = fixtag(v, namespaces) if xmlns: xmlns_items.append(xmlns) except TypeError: _raise_serialization_error(v) tree_string += " %s=\"%s\"" % (_encode(k, encoding), _escape_attrib(v, encoding)) for k, v in xmlns_items: tree_string += " %s=\"%s\"" % (_encode(k, encoding), _escape_attrib(v, encoding)) tree_string += ">" if node.text: tree_string += _escape_cdata(node.text, encoding).replace('"', '"') for n in node: tree_string += self._print_node(n, encoding) tree_string += "</" + _encode(tag, encoding) + ">" for k, v in xmlns_items: del namespaces[v] if node.tail: tree_string += _escape_cdata(node.tail, encoding) return tree_string