26 sys.path.append(os.path.dirname(__file__))
34 if sys.version_info[0] == 3:
38 _xml11_illegal_ranges = (
44 _xml10_illegal_ranges = _xml11_illegal_ranges + (
50 _xml_discouraged_ranges = (
55 if sys.maxunicode >= 0x10000:
57 _xml_discouraged_ranges = _xml_discouraged_ranges + (
73 (0x10fffe, 0x10ffff,),
77 def _range_seq_to_re(range_seq):
79 return re.compile(
u"[{}]".format(
81 u"{}-{}".format(re.escape(
unichr(lo)), re.escape(
unichr(hi)))
82 for lo, hi
in range_seq
86 _xml_filtered_chars_re = _range_seq_to_re(_xml10_illegal_ranges + _xml_discouraged_ranges)
88 def _handle_unrepresentable(data):
89 return _xml_filtered_chars_re.sub(
u"\ufffd", data)
101 def _escape(data, entities={}):
102 data = data.replace(
"&",
"&")
103 data = data.replace(
"<",
"<")
104 data = data.replace(
">",
">")
105 for chars, entity
in entities.items():
106 data = data.replace(chars, entity)
109 def _sanitize(data, entities={}):
110 return _escape(_handle_unrepresentable(data), entities=entities)
123 def _quoteattr(data, entities={}):
124 entities[
'\n']=
' '
125 entities[
'\r']=
''
126 data = _sanitize(data, entities)
129 data =
'"%s"' % data.replace(
'"',
""")
138 def _nssplit(qualifiedName):
139 fields = qualifiedName.split(
':', 1)
143 return (
None, fields[0])
145 def _nsassign(namespace):
146 return nsdict.setdefault(namespace,
"ns" + str(len(nsdict)))
162 previousSibling =
None
174 def _get_childNodes(self):
175 return self.childNodes
177 def _get_firstChild(self):
179 return self.childNodes[0]
181 def _get_lastChild(self):
183 return self.childNodes[-1]
190 if newChild.nodeType
not in self._child_node_types:
191 raise IllegalChild(
"%s cannot be child of %s" % (newChild.tagName, self.tagName))
192 if newChild.parentNode
is not None:
193 newChild.parentNode.removeChild(newChild)
198 index = self.childNodes.index(refChild)
200 raise xml.dom.NotFoundErr()
201 self.childNodes.insert(index, newChild)
202 newChild.nextSibling = refChild
203 refChild.previousSibling = newChild
205 node = self.childNodes[index-1]
206 node.nextSibling = newChild
207 newChild.previousSibling = node
209 newChild.previousSibling =
None
210 newChild.parentNode = self
218 if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
219 for c
in tuple(newChild.childNodes):
223 if newChild.nodeType
not in self._child_node_types:
224 raise IllegalChild(
"<%s> is not allowed in %s" % ( newChild.tagName, self.tagName))
225 if newChild.parentNode
is not None:
226 newChild.parentNode.removeChild(newChild)
227 _append_child(self, newChild)
228 newChild.nextSibling =
None
237 self.childNodes.remove(oldChild)
239 raise xml.dom.NotFoundErr()
240 if oldChild.nextSibling
is not None:
241 oldChild.nextSibling.previousSibling = oldChild.previousSibling
242 if oldChild.previousSibling
is not None:
243 oldChild.previousSibling.nextSibling = oldChild.nextSibling
244 oldChild.nextSibling = oldChild.previousSibling =
None
245 if self.ownerDocument:
246 self.ownerDocument.clear_caches()
247 oldChild.parentNode =
None
252 for c
in self.childNodes:
258 for c
in self.childNodes:
262 defproperty(Node,
"firstChild", doc=
"First child node, or None.")
263 defproperty(Node,
"lastChild", doc=
"Last child node, or None.")
265 def _append_child(self, node):
267 childNodes = self.childNodes
269 last = childNodes[-1]
270 node.__dict__[
"previousSibling"] = last
271 last.__dict__[
"nextSibling"] = node
272 childNodes.append(node)
273 node.__dict__[
"parentNode"] = self
282 childNodes = EmptyNodeList()
286 def _get_firstChild(self):
289 def _get_lastChild(self):
295 raise xml.dom.HierarchyRequestErr(
296 self.tagName +
" nodes cannot have children")
304 raise xml.dom.HierarchyRequestErr(
305 self.tagName +
" nodes do not have children")
310 raise xml.dom.NotFoundErr(
311 self.tagName +
" nodes do not have children")
316 raise xml.dom.HierarchyRequestErr(
317 self.tagName +
" nodes do not have children")
320 nodeType = Node.TEXT_NODE
339 nodeType = Node.CDATA_SECTION_NODE
348 f.write(
'<![CDATA[%s]]>' % self.
data.replace(
']]>',
']]>]]><![CDATA['))
359 nodeType = Node.ELEMENT_NODE
362 _child_node_types = (Node.ELEMENT_NODE,
363 Node.PROCESSING_INSTRUCTION_NODE,
366 Node.CDATA_SECTION_NODE,
367 Node.ENTITY_REFERENCE_NODE)
369 def __init__(self, attributes=None, text=None, cdata=None, qname=None, qattributes=None, check_grammar=True, **args):
370 if qname
is not None:
372 assert(hasattr(self,
'qname'))
380 if cdata
is not None:
384 if allowed_attrs
is not None:
385 allowed_args = [ a[1].lower().replace(
'-',
'')
for a
in allowed_attrs]
389 for attr, value
in attributes.items():
393 for attr, value
in qattributes.items():
395 if allowed_attrs
is not None:
397 for arg
in args.keys():
400 for arg
in args.keys():
402 if not check_grammar:
405 required = grammar.required_attributes.get(self.
qname)
409 raise AttributeError(
"Required attribute missing: %s in <%s>" % (r[1].lower().replace(
'-',
''), self.
tagName))
417 for ns,p
in nsdict.items():
418 if p == prefix:
return ns
426 if namespace
is None: namespace =
""
427 prefix = _nsassign(namespace)
433 return grammar.allowed_attributes.get(self.
qname)
435 def _setOwnerDoc(self, element):
437 for child
in element.childNodes:
459 if check_grammar
and self.
qname not in grammar.allows_text:
470 if check_grammar
and self.
qname not in grammar.allows_text:
479 if allowed_attrs
is None:
480 if type(attr) == type(()):
481 prefix, localname = attr
484 raise AttributeError(
"Unable to add simple attribute - use (namespace, localpart)")
487 allowed_args = [ a[1].lower().replace(
'-',
'')
for a
in allowed_attrs]
488 if check_grammar
and attr
not in allowed_args:
489 raise AttributeError(
"Attribute %s is not allowed in <%s>" % ( attr, self.
tagName))
490 i = allowed_args.index(attr)
491 self.
removeAttrNS(allowed_attrs[i][0], allowed_attrs[i][1])
502 if attr ==
'parent' and value
is not None:
503 value.addElement(self)
506 if allowed_attrs
is None:
507 if type(attr) == type(()):
508 prefix, localname = attr
511 raise AttributeError(
"Unable to add simple attribute - use (namespace, localpart)")
514 allowed_args = [ a[1].lower().replace(
'-',
'')
for a
in allowed_attrs]
515 if check_grammar
and attr
not in allowed_args:
516 raise AttributeError(
"Attribute %s is not allowed in <%s>" % ( attr, self.
tagName))
517 i = allowed_args.index(attr)
518 self.
setAttrNS(allowed_attrs[i][0], allowed_attrs[i][1], value)
533 self.
attributes[(namespace, localpart)] = c.convert((namespace, localpart), value, self)
547 result = self.
attributes.get((namespace, localpart))
550 (type(namespace), type(namespace), type(namespace) == \
551 type(b
""), type(b
""), type(b
""))
or
552 (type(namespace), type(namespace), type(namespace) == \
553 type(
u""), type(
u""), type(
u""))
566 if allowed_attrs
is None:
567 if type(attr) == type(()):
568 prefix, localname = attr
571 raise AttributeError(
"Unable to get simple attribute - use (namespace, localpart)")
574 allowed_args = [ a[1].lower().replace(
'-',
'')
for a
in allowed_attrs]
575 i = allowed_args.index(attr)
576 return self.
getAttrNS(allowed_attrs[i][0], allowed_attrs[i][1])
581 for namespace, prefix
in self.
namespaces.items():
582 f.write(
u' xmlns:' + prefix +
u'="'+ _sanitize(str(namespace))+
'"')
585 f.write(
u' '+_sanitize(str(prefix+
u':'+qname[1]))+
u'='+_quoteattr(
unicode(self.
attributes[qname])))
600 for namespace, prefix
in self.
namespaces.items():
601 f.write(
u' xmlns:' + prefix +
u'="'+ _sanitize(str(namespace))+
u'"')
608 element.toXml(level+1,f)
609 f.write(
u'</'+self.
tagName+
'>')
613 def _getElementsByObj(self, obj, accumulator):
614 if self.
qname == obj.qname:
615 accumulator.append(self)
617 if e.nodeType == Node.ELEMENT_NODE:
618 accumulator = e._getElementsByObj(obj, accumulator)
624 obj = element(check_grammar=
False)
630 obj = element(check_grammar=
False)
631 return self.
qname == obj.qname