######################################################################## # XML Utilities # By Don Hopkins, BNS. ######################################################################## import xml, xml.dom.minidom, xml.parsers.expat, pyexpat, string, re ######################################################################## def ParseXMLFile(fileName): doc = xml.dom.minidom.parse(fname) return doc def ParseXMLString(str): doc = xml.dom.minidom.parseString(str) return doc def SetAtt(n, name, val): n.setAttribute( name, unicode(val)) def GetAttStr(n, name, default=''): if n.hasAttribute(name): val = n.getAttribute(name).encode() return val else: return default def GetAttInt(n, name, default=0): if n.hasAttribute(name): val = n.getAttribute(name).encode() num = 0 try: num = int(val) except: num = default return num else: return default def GetAttFloat(n, name, default=0.0): if n.hasAttribute(name): val = n.getAttribute(name).encode() num = default try: num = float(val) except: num = default return num else: return default TrueStrings = ( 't', 'true', 'yes', 'y', 'on', '+', '1' ) FalseStrings = ( 'f', 'false', 'nil', 'no', 'n', 'off', '-', '0' ) def GetAttBool(n, name, default=0): if n.hasAttribute(name): val = n.getAttribute(name).encode().lower() if val in TrueStrings: return 1 if val in FalseStrings: return 0 num = 0 try: num = int(val) except: num = default if num != 0: return 1 else: return 0 else: return default def GetAttEval(n, name, default=None): if n.hasAttribute(name): s = n.getAttribute(name).encode() try: val = eval(s) except: val = default return val else: return default def GetNodeText(n): if n.nodeType == n.TEXT_NODE: return n.data s = '' if n.nodeType == n.ELEMENT_NODE: n = n.firstChild while n != None: s += GetNodeText(n) n = n.nextSibling return s def NormalizeWhiteSpace(str): return(str.replace('\r\n', '\n').replace('\r', '\n')) def QuoteForAtt(str): return str.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"') def QuoteForText(str): return str.replace('&', '&').replace('<', '<').replace('>', '>') WhiteSpace = '\n\r\t ' def StripIgnorableWhiteSpace(str): beginning = 0 ending = len(str) while (beginning < ending) and (str[beginning] in WhiteSpace): beginning += 1 while (ending > beginning) and (str[ending - 1] in WhiteSpace): ending -= 1 return str[beginning:ending] def _get_StringIO(): # we can't use cStringIO since it doesn't support Unicode strings from StringIO import StringIO return StringIO() def _write_data(writer, data): "Writes datachars to writer." replace = string.replace data = replace(data, "&", "&") data = replace(data, "<", "<") data = replace(data, "\"", """) data = replace(data, ">", ">") writer.write(data) def CompactPrintXML(el): return PrettyPrintXML(el, indent="", attindent=" ", newl="") def PrettyPrintXML(el, indent=" ", attindent=" ", newl="\n"): writer = _get_StringIO() PrettyWriteXML(el, writer, "", indent, attindent, newl) return writer.getvalue() def PrettyWriteXML(el, writer, indent="", addindent="", attindent="", newl=""): # indent = current indentation # attindent = current indentation # addindent = indentation to add to higher levels # newl = newline string if el.nodeType == el.ELEMENT_NODE: attrs = el._get_attributes() a_names = attrs.keys() a_names.sort() writer.write(indent + "<" + el.tagName) if len(a_names): writer.write(newl) for a_name in a_names: writer.write(indent + attindent + a_name + "=\"") _write_data(writer, attrs[a_name].value) writer.write("\"") if a_name != a_names[-1]: writer.write(newl) if el.childNodes: writer.write(">" + newl) for node in el.childNodes: PrettyWriteXML(node, writer, indent + addindent, addindent, attindent, newl) writer.write(indent + "" + newl) else: writer.write(indent + "/>" + newl) return if el.nodeType == el.TEXT_NODE: writer.write(indent) s = StripIgnorableWhiteSpace(el.data) _write_data(writer, s) writer.write(newl) return if el.nodeType == el.COMMENT_NODE: writer.write(indent + "" + newl) return ########################################################################