26 sys.path.append(os.path.dirname(__file__))
 
   29 from namespaces 
import nsdict
 
   31 from attrconverters 
import AttrConverters
 
   33 if sys.version_info.major == 3:
 
   46 def _escape(data, entities={}):
 
   47     data = data.replace(
"&", 
"&")
 
   48     data = data.replace(
"<", 
"<")
 
   49     data = data.replace(
">", 
">")
 
   50     for chars, entity 
in entities.items():
 
   51         data = data.replace(chars, entity)
 
   65 def _quoteattr(data, entities={}):
 
   66     entities[
'\n']=
'
' 
   67     entities[
'\r']=
'' 
   68     data = _escape(data, entities)
 
   71             data = 
'"%s"' % data.replace(
'"', 
""")
 
   80 def _nssplit(qualifiedName):
 
   81     fields = qualifiedName.split(
':', 1)
 
   85         return (
None, fields[0])
 
   87 def _nsassign(namespace):
 
   88     return nsdict.setdefault(namespace,
"ns" + str(len(nsdict)))
 
  104     previousSibling = 
None 
  116     def _get_childNodes(self):
 
  117         return self.childNodes
 
  119     def _get_firstChild(self):
 
  121             return self.childNodes[0]
 
  123     def _get_lastChild(self):
 
  125             return self.childNodes[-1]
 
  132         if newChild.nodeType 
not in self._child_node_types:
 
  133             raise IllegalChild( 
"%s cannot be child of %s" % (newChild.tagName, self.tagName))
 
  134         if newChild.parentNode 
is not None:
 
  135             newChild.parentNode.removeChild(newChild)
 
  140                 index = self.childNodes.index(refChild)
 
  142                 raise xml.dom.NotFoundErr()
 
  143             self.childNodes.insert(index, newChild)
 
  144             newChild.nextSibling = refChild
 
  145             refChild.previousSibling = newChild
 
  147                 node = self.childNodes[index-1]
 
  148                 node.nextSibling = newChild
 
  149                 newChild.previousSibling = node
 
  151                 newChild.previousSibling = 
None 
  152             newChild.parentNode = self
 
  160         if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE:
 
  161             for c 
in tuple(newChild.childNodes):
 
  165         if newChild.nodeType 
not in self._child_node_types:
 
  166             raise IllegalChild( 
"<%s> is not allowed in %s" % ( newChild.tagName, self.tagName))
 
  167         if newChild.parentNode 
is not None:
 
  168             newChild.parentNode.removeChild(newChild)
 
  169         _append_child(self, newChild)
 
  170         newChild.nextSibling = 
None 
  179             self.childNodes.remove(oldChild)
 
  181             raise xml.dom.NotFoundErr()
 
  182         if oldChild.nextSibling 
is not None:
 
  183             oldChild.nextSibling.previousSibling = oldChild.previousSibling
 
  184         if oldChild.previousSibling 
is not None:
 
  185             oldChild.previousSibling.nextSibling = oldChild.nextSibling
 
  186         oldChild.nextSibling = oldChild.previousSibling = 
None 
  187         if self.ownerDocument:
 
  188             self.ownerDocument.clear_caches()
 
  189         oldChild.parentNode = 
None 
  194         for c 
in self.childNodes:
 
  200         for c 
in self.childNodes:
 
  204 defproperty(Node, 
"firstChild", doc=
"First child node, or None.")
 
  205 defproperty(Node, 
"lastChild",  doc=
"Last child node, or None.")
 
  207 def _append_child(self, node):
 
  209     childNodes = self.childNodes
 
  211         last = childNodes[-1]
 
  212         node.__dict__[
"previousSibling"] = last
 
  213         last.__dict__[
"nextSibling"] = node
 
  214     childNodes.append(node)
 
  215     node.__dict__[
"parentNode"] = self
 
  224     childNodes = EmptyNodeList()
 
  228     def _get_firstChild(self):
 
  231     def _get_lastChild(self):
 
  237         raise xml.dom.HierarchyRequestErr(
 
  238             self.tagName + 
" nodes cannot have children")
 
  246         raise xml.dom.HierarchyRequestErr(
 
  247             self.tagName + 
" nodes do not have children")
 
  252         raise xml.dom.NotFoundErr(
 
  253             self.tagName + 
" nodes do not have children")
 
  258         raise xml.dom.HierarchyRequestErr(
 
  259             self.tagName + 
" nodes do not have children")
 
  262     nodeType = Node.TEXT_NODE
 
  281     nodeType = Node.CDATA_SECTION_NODE
 
  290             f.write(
'<![CDATA[%s]]>' % self.data.replace(
']]>',
']]>]]><![CDATA['))
 
  301     nodeType = Node.ELEMENT_NODE
 
  304     _child_node_types = (Node.ELEMENT_NODE,
 
  305                          Node.PROCESSING_INSTRUCTION_NODE,
 
  308                          Node.CDATA_SECTION_NODE,
 
  309                          Node.ENTITY_REFERENCE_NODE)
 
  311     def __init__(self, attributes=None, text=None, cdata=None, qname=None, qattributes=None, check_grammar=True, **args):
 
  312         if qname 
is not None:
 
  314         assert(hasattr(self, 
'qname'))
 
  322         if cdata 
is not None:
 
  326         if allowed_attrs 
is not None:
 
  327             allowed_args = [ a[1].lower().replace(
'-',
'') 
for a 
in allowed_attrs]
 
  331             for attr, value 
in attributes.items():
 
  335             for attr, value 
in qattributes.items():
 
  337         if allowed_attrs 
is not None:
 
  339             for arg 
in args.keys():
 
  342             for arg 
in args.keys():  
 
  344         if not check_grammar:
 
  347         required = grammar.required_attributes.get(self.
qname)
 
  351                     raise AttributeError( 
"Required attribute missing: %s in <%s>" % (r[1].lower().replace(
'-',
''), self.
tagName))
 
  359         for ns,p 
in nsdict.items():
 
  360             if p == prefix: 
return ns
 
  368         if namespace 
is None: namespace = 
"" 
  369         prefix = _nsassign(namespace)
 
  375         return grammar.allowed_attributes.get(self.
qname)
 
  377     def _setOwnerDoc(self, element):
 
  379         for child 
in element.childNodes:
 
  394             self.ownerDocument.rebuild_caches(element)
 
  401         if check_grammar 
and self.
qname not in grammar.allows_text:
 
  412         if check_grammar 
and self.
qname not in grammar.allows_text:
 
  421         if allowed_attrs 
is None:
 
  422             if type(attr) == type(()):
 
  423                 prefix, localname = attr
 
  426                 raise AttributeError( 
"Unable to add simple attribute - use (namespace, localpart)")
 
  429             allowed_args = [ a[1].lower().replace(
'-',
'') 
for a 
in allowed_attrs]
 
  430             if check_grammar 
and attr 
not in allowed_args:
 
  431                 raise AttributeError( 
"Attribute %s is not allowed in <%s>" % ( attr, self.
tagName))
 
  432             i = allowed_args.index(attr)
 
  433             self.
removeAttrNS(allowed_attrs[i][0], allowed_attrs[i][1])
 
  445         if allowed_attrs 
is None:
 
  446             if type(attr) == type(()):
 
  447                 prefix, localname = attr
 
  450                 raise AttributeError( 
"Unable to add simple attribute - use (namespace, localpart)")
 
  453             allowed_args = [ a[1].lower().replace(
'-',
'') 
for a 
in allowed_attrs]
 
  454             if check_grammar 
and attr 
not in allowed_args:
 
  455                 raise AttributeError( 
"Attribute %s is not allowed in <%s>" % ( attr, self.
tagName))
 
  456             i = allowed_args.index(attr)
 
  457             self.
setAttrNS(allowed_attrs[i][0], allowed_attrs[i][1], value)
 
  472         self.
attributes[(namespace, localpart)] = c.convert((namespace, localpart), value, self)
 
  486         result = self.attributes.get((namespace, localpart))
 
  489             (type(namespace), type(namespace), type(namespace) == \
 
  490                  type(b
""), type(b
""), type(b
"")) 
or 
  491             (type(namespace), type(namespace), type(namespace) == \
 
  492                  type(
u""), type(
u""), type(
u""))
 
  505         if allowed_attrs 
is None:
 
  506             if type(attr) == type(()):
 
  507                 prefix, localname = attr
 
  510                 raise AttributeError( 
"Unable to get simple attribute - use (namespace, localpart)")
 
  513             allowed_args = [ a[1].lower().replace(
'-',
'') 
for a 
in allowed_attrs]
 
  514             i = allowed_args.index(attr)
 
  515             return self.
getAttrNS(allowed_attrs[i][0], allowed_attrs[i][1])
 
  520             for namespace, prefix 
in self.namespaces.items():
 
  521                 f.write(
u' xmlns:' + prefix + 
u'="'+ _escape(str(namespace))+
'"')
 
  522         for qname 
in self.attributes.keys():
 
  524             f.write(
u' '+_escape(str(prefix+
u':'+qname[1]))+
u'='+_quoteattr(
unicode(self.
attributes[qname])))
 
  539             for namespace, prefix 
in self.namespaces.items():
 
  540                 f.write(
u' xmlns:' + prefix + 
u'="'+ _escape(str(namespace))+
u'"')
 
  541         for qname 
in self.attributes.keys():
 
  547                 element.toXml(level+1,f)
 
  548             f.write(
u'</'+self.
tagName+
'>')
 
  552     def _getElementsByObj(self, obj, accumulator):
 
  553         if self.
qname == obj.qname:
 
  554             accumulator.append(self)
 
  556             if e.nodeType == Node.ELEMENT_NODE:
 
  557                 accumulator = e._getElementsByObj(obj, accumulator)
 
  563         obj = element(check_grammar=
False)
 
  569         obj = element(check_grammar=
False)
 
  570         return self.
qname == obj.qname
 
def removeChild
Raises an error. 
def toXml
Generate XML output of the node. 
def get_nsprefix
Odfpy maintains a list of known namespaces. 
super class for more specific nodes 
def toXml
Write XML in UTF-8. 
def addElement
adds an element to an Element 
def isInstanceOf
This is a check to see if the object is an instance of a type. 
def getAttribute
Get an attribute value. 
def addText
Adds text to an element Setting check_grammar=False turns off grammar checking. 
Complains if you add text or cdata to an element where it is not allowed. 
def replaceChild
Raises an error. 
def getAttrNS
gets an attribute, given a namespace and a key 
Complains if you add an element to a parent where it is not allowed. 
def removeAttribute
Removes an attribute by name. 
Mixin that makes childless-ness easy to implement and avoids the complexity of the Node methods that ...
def appendChild
Adds the node newChild to the end of the list of children of this node. 
def setAttribute
Add an attribute to the element This is sort of a convenience method. 
def toXml
Generate an XML stream out of the tree structure. 
def insertBefore
Inserts the node newChild before the existing child node refChild. 
def insertBefore
Raises an error. 
Creates a arbitrary element and is intended to be subclassed not used on its own. ...
def hasChildNodes
Tells whether this element has any children; text nodes, subelements, whatever. 
def get_knownns
Odfpy maintains a list of known namespaces. 
def getElementsByType
Gets elements based on the type, which is function from text.py, draw.py etc. 
def addCDATA
Adds CDATA to an element Setting check_grammar=False turns off grammar checking. 
def removeChild
Removes the child node indicated by oldChild from the list of children, and returns it...
def appendChild
Raises an error. 
def setAttrNS
Add an attribute to the element In case you need to add an attribute the library doesn't know about t...