Package caldavclientlibrary :: Package protocol :: Package utils :: Module xmlhelpers
[hide private]
[frames] | no frames]

Source Code for Module caldavclientlibrary.protocol.utils.xmlhelpers

  1  ## 
  2  # Copyright (c) 2007-2016 Apple Inc. All rights reserved. 
  3  # 
  4  # Licensed under the Apache License, Version 2.0 (the "License"); 
  5  # you may not use this file except in compliance with the License. 
  6  # You may obtain a copy of the License at 
  7  # 
  8  # http://www.apache.org/licenses/LICENSE-2.0 
  9  # 
 10  # Unless required by applicable law or agreed to in writing, software 
 11  # distributed under the License is distributed on an "AS IS" BASIS, 
 12  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 13  # See the License for the specific language governing permissions and 
 14  # limitations under the License. 
 15  ## 
 16   
 17  from xml.etree.ElementTree import ElementTree, _namespace_map 
 18  from xml.etree.ElementTree import Comment 
 19  from xml.etree.ElementTree import _escape_cdata 
 20  from xml.etree.ElementTree import ProcessingInstruction 
 21  from xml.etree.ElementTree import QName 
 22  from xml.etree.ElementTree import _raise_serialization_error 
 23  from xml.etree.ElementTree import _encode 
 24  from xml.etree.ElementTree import _escape_attrib 
 25  from StringIO import StringIO 
 26  from xml.etree.ElementTree import SubElement 
 27  import string 
 28   
29 -def SubElementWithData(parent, tag, data=None, attrs={}):
30 element = SubElement(parent, tag, attrs) 31 if data: 32 element.text = data 33 return element
34
35 -def myfixtag(tag, namespaces):
36 # given a decorated tag (of the form {uri}tag), return prefixed 37 # tag and namespace declaration, if any 38 if isinstance(tag, QName): 39 tag = tag.text 40 namespace_uri, tag = string.split(tag[1:], "}", 1) 41 prefix = namespaces.get(namespace_uri) 42 if prefix is None: 43 prefix = _namespace_map.get(namespace_uri) 44 if prefix is None: 45 prefix = "ns%d" % len(namespaces) 46 namespaces[namespace_uri] = prefix 47 if prefix == "xml": 48 xmlns = None 49 else: 50 xmlns = ("xmlns:%s" % prefix, namespace_uri) 51 else: 52 xmlns = None 53 return "%s:%s" % (prefix, tag), xmlns
54
55 -class BetterElementTree(ElementTree):
56
57 - def writeUTF8(self, file):
58 assert self._root is not None 59 if not hasattr(file, "write"): 60 file = open(file, "wb") 61 encoding = "utf-8" 62 file.write("<?xml version='1.0' encoding='%s'?>" % encoding) 63 self._prettywrite(file, self._root, encoding, {}) 64 file.write("\r\n")
65
66 - def _prettywrite(self, file, node, encoding, namespaces, depth=0):
67 # write XML to file 68 tag = node.tag 69 if tag is Comment: 70 file.write("\r\n" + " " * depth) 71 file.write("<!-- %s -->" % _escape_cdata(node.text, encoding)) 72 elif tag is ProcessingInstruction: 73 file.write("\r\n" + " " * depth) 74 file.write("<?%s?>" % _escape_cdata(node.text, encoding)) 75 else: 76 items = node.items() 77 xmlns_items = [] # new namespaces in this scope 78 try: 79 if isinstance(tag, QName) or tag[:1] == "{": 80 tag, xmlns = myfixtag(tag, namespaces) 81 if xmlns: xmlns_items.append(xmlns) 82 except TypeError: 83 _raise_serialization_error(tag) 84 file.write("\r\n" + " " * depth) 85 file.write("<" + _encode(tag, encoding)) 86 if items or xmlns_items: 87 items.sort() # lexical order 88 for k, v in items: 89 try: 90 if isinstance(k, QName) or k[:1] == "{": 91 k, xmlns = myfixtag(k, namespaces) 92 if xmlns: xmlns_items.append(xmlns) 93 except TypeError: 94 _raise_serialization_error(k) 95 try: 96 if isinstance(v, QName): 97 v, xmlns = myfixtag(v, namespaces) 98 if xmlns: xmlns_items.append(xmlns) 99 except TypeError: 100 _raise_serialization_error(v) 101 file.write(" %s=\"%s\"" % (_encode(k, encoding), 102 _escape_attrib(v, encoding))) 103 for k, v in xmlns_items: 104 file.write(" %s=\"%s\"" % (_encode(k, encoding), 105 _escape_attrib(v, encoding))) 106 if node.text or len(node): 107 file.write(">") 108 if node.text: 109 file.write(_escape_cdata(node.text, encoding)) 110 for n in node: 111 self._prettywrite(file, n, encoding, namespaces, depth=depth+1) 112 if not node.text or len(node): 113 file.write("\r\n" + " " * depth) 114 file.write("</" + _encode(tag, encoding) + ">") 115 else: 116 file.write(" />") 117 for k, v in xmlns_items: 118 del namespaces[v] 119 if node.tail: 120 file.write(_escape_cdata(node.tail, encoding))
121
122 -def elementToString(element):
123 os = StringIO() 124 xmldoc = BetterElementTree(element) 125 xmldoc.writeUTF8(os) 126 return os.getvalue()
127