00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 import string
00044 import copy
00045 import urllib
00046 from types import TupleType
00047 from xml.dom import Node, getDOMImplementation, XMLNS_NAMESPACE
00048 from ..genxmlif import XINC_NAMESPACE, GenXmlIfError
00049 from xmlifUtils import nsNameToQName, processWhitespaceAction, collapseString, NsNameTupleFactory, convertToAbsUrl
00050 from xmlifBase import XmlIfBuilderExtensionBase
00051 from xmlifApi import XmlInterfaceBase
00052
00053
00054 class XmlInterfaceDom (XmlInterfaceBase):
00055 """Derived interface class for handling of DOM parsers.
00056
00057 For description of the interface methods see xmlifbase.py.
00058 """
00059
00060 def xInclude (self, elementWrapper, baseUrl, ownerDoc):
00061 filePath = elementWrapper.getFilePath()
00062 for childElementWrapper in elementWrapper.getChildren():
00063 line = childElementWrapper.getStartLineNumber()
00064 if childElementWrapper.getNsName() == (XINC_NAMESPACE, "include"):
00065 href = childElementWrapper["href"]
00066 parse = childElementWrapper.getAttributeOrDefault ("parse", "xml")
00067 encoding = childElementWrapper.getAttribute ("encoding")
00068 if self.verbose:
00069 print "Xinclude: %s" %href
00070 try:
00071 if parse == "xml":
00072 subTreeWrapper = self.parse (href, baseUrl, ownerDoc)
00073 elementWrapper.replaceChildBySubtree (childElementWrapper, subTreeWrapper)
00074 elif parse == "text":
00075 absUrl = convertToAbsUrl (href, baseUrl)
00076 fp = urllib.urlopen (absUrl)
00077 data = fp.read()
00078 if encoding:
00079 data = data.decode(encoding)
00080 newTextNode = ownerDoc.xmlIfExtCreateTextNode(data)
00081 elementWrapper.element.element.insertBefore (newTextNode, childElementWrapper.element.element)
00082 elementWrapper.removeChild (childElementWrapper)
00083 fp.close()
00084 else:
00085 raise GenXmlIfError, "%s: line %s: XIncludeError: Invalid 'parse' Attribut: '%s'" %(filePath, line, parse)
00086 except IOError, errInst:
00087 raise GenXmlIfError, "%s: line %s: IOError: %s" %(filePath, line, str(errInst))
00088 elif childElementWrapper.getNsName() == (XINC_NAMESPACE, "fallback"):
00089 raise GenXmlIfError, "%s: line %s: XIncludeError: xi:fallback tag must be child of xi:include" %(filePath, line)
00090 else:
00091 self.xInclude(childElementWrapper, baseUrl, ownerDoc)
00092
00093
00094
00095 class InternalDomTreeWrapper:
00096 """Internal wrapper for a DOM Document class.
00097 """
00098 def __init__ (self, document):
00099 self.document = document
00100
00101 def xmlIfExtGetRootNode (self):
00102 domNode = self.document
00103 if domNode.nodeType == Node.DOCUMENT_NODE:
00104 return domNode.documentElement.xmlIfExtInternalWrapper
00105 elif domNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
00106 for node in domNode.childNodes:
00107 if node.nodeType == Node.ELEMENT_NODE:
00108 return node.xmlIfExtInternalWrapper
00109 else:
00110 return None
00111 else:
00112 return None
00113
00114
00115 def xmlIfExtCreateElement (self, nsName, attributeDict, curNs):
00116 elementNode = self.document.createElementNS (nsName[0], nsName[1])
00117 intElementWrapper = self.internalElementWrapperClass(elementNode, self)
00118 for attrName, attrValue in attributeDict.items():
00119 intElementWrapper.xmlIfExtSetAttribute (NsNameTupleFactory(attrName), attrValue, curNs)
00120 return intElementWrapper
00121
00122
00123 def xmlIfExtCreateTextNode (self, data):
00124 return self.document.createTextNode(data)
00125
00126
00127 def xmlIfExtImportNode (self, node):
00128 return self.document.importNode (node, 0)
00129
00130
00131 def xmlIfExtCloneTree (self, rootElementCopy):
00132 domImpl = getDOMImplementation()
00133
00134 documentCopy = domImpl.createDocument(None, None, None)
00135
00136 documentCopy.documentElement = rootElementCopy.element
00137 return self.__class__(documentCopy)
00138
00139
00140
00141
00142
00143
00144 class InternalDomElementWrapper:
00145 """Internal Wrapper for a Dom Element class.
00146 """
00147
00148 def __init__ (self, element, internalDomTreeWrapper):
00149 self.element = element
00150 element.xmlIfExtInternalWrapper = self
00151 self.internalDomTreeWrapper = internalDomTreeWrapper
00152
00153
00154 def xmlIfExtUnlink (self):
00155 self.xmlIfExtElementWrapper = None
00156
00157
00158 def xmlIfExtCloneNode (self):
00159 nodeCopy = self.__class__(self.element.cloneNode(deep=0), self.internalDomTreeWrapper)
00160 for childTextNode in self.__xmlIfExtGetChildTextNodes():
00161 childTextNodeCopy = childTextNode.cloneNode(0)
00162 nodeCopy.element.appendChild (childTextNodeCopy)
00163
00164
00165 return nodeCopy
00166
00167
00168 def xmlIfExtGetTagName (self):
00169 return self.element.tagName
00170
00171
00172 def xmlIfExtGetNamespaceURI (self):
00173 return self.element.namespaceURI
00174
00175
00176 def xmlIfExtGetParentNode (self):
00177 parentNode = self.element.parentNode
00178 if parentNode.nodeType == Node.ELEMENT_NODE:
00179 return self.element.parentNode.xmlIfExtInternalWrapper
00180 else:
00181 return None
00182
00183
00184 def xmlIfExtSetParentNode (self, parentElement):
00185 pass
00186
00187
00188 def xmlIfExtGetChildren (self, tagFilter=None):
00189
00190 children = filter (lambda e: (e.nodeType == Node.ELEMENT_NODE) and
00191 (tagFilter == None or
00192 (e.namespaceURI == tagFilter[0] and e.localName == tagFilter[1])),
00193 self.element.childNodes )
00194
00195 return map(lambda element: element.xmlIfExtInternalWrapper, children)
00196
00197
00198 def xmlIfExtGetFirstChild (self, tagFilter=None):
00199 children = self.xmlIfExtGetChildren (tagFilter)
00200 if children != []:
00201 return children[0]
00202 else:
00203 None
00204
00205
00206 def xmlIfExtGetElementsByTagName (self, tagFilter=('*','*')):
00207 elementList = self.element.getElementsByTagNameNS( tagFilter[0], tagFilter[1] )
00208 return map( lambda element: element.xmlIfExtInternalWrapper, elementList )
00209
00210
00211 def xmlIfExtGetIterator (self, tagFilter=('*','*')):
00212 elementList = []
00213 if tagFilter in (('*','*'), (self.element.namespaceURI, self.element.localName)):
00214 elementList.append(self.element)
00215 elementList.extend(self.element.getElementsByTagNameNS( tagFilter[0], tagFilter[1] ))
00216 return map( lambda element: element.xmlIfExtInternalWrapper, elementList )
00217
00218
00219 def xmlIfExtAppendChild (self, childElement):
00220 self.element.appendChild (childElement.element)
00221
00222
00223 def xmlIfExtInsertBefore (self, childElement, refChildElement):
00224 self.element.insertBefore (childElement.element, refChildElement.element)
00225
00226
00227 def xmlIfExtRemoveChild (self, childElement):
00228 self.element.removeChild (childElement.element)
00229
00230
00231 def xmlIfExtInsertSubtree (self, refChildElement, subTree, insertSubTreeRootNode):
00232 if insertSubTreeRootNode:
00233 childElementList = [subTree.xmlIfExtGetRootNode(),]
00234 else:
00235 childElementList = subTree.xmlIfExtGetRootNode().xmlIfExtGetChildren()
00236
00237 for childElement in childElementList:
00238 if refChildElement != None:
00239 self.element.insertBefore(childElement.element, refChildElement.element)
00240 else:
00241 self.element.appendChild(childElement.element)
00242
00243
00244 def xmlIfExtGetAttributeDict (self):
00245 attribDict = {}
00246 for nsAttrName, attrNodeOrValue in self.element.attributes.items():
00247 attribDict[NsNameTupleFactory(nsAttrName)] = attrNodeOrValue.nodeValue
00248 return attribDict
00249
00250
00251 def xmlIfExtGetAttribute (self, nsAttrName):
00252 if self.element.attributes.has_key (nsAttrName):
00253 return self.element.getAttributeNS (nsAttrName[0], nsAttrName[1])
00254 elif nsAttrName[1] == "xmlns" and self.element.attributes.has_key(nsAttrName[1]):
00255
00256 return self.element.getAttribute (nsAttrName[1])
00257 else:
00258 return None
00259
00260
00261 def xmlIfExtSetAttribute (self, nsAttrName, attributeValue, curNs):
00262 if nsAttrName[0] != None:
00263 qName = nsNameToQName (nsAttrName, curNs)
00264 else:
00265 qName = nsAttrName[1]
00266
00267 self.element.setAttributeNS (nsAttrName[0], qName, attributeValue)
00268
00269
00270 def xmlIfExtRemoveAttribute (self, nsAttrName):
00271 self.element.removeAttributeNS (nsAttrName[0], nsAttrName[1])
00272
00273
00274 def xmlIfExtGetElementValueFragments (self, ignoreEmtpyStringFragments):
00275 elementValueList = []
00276 for childTextNode in self.__xmlIfExtGetChildTextNodes():
00277 elementValueList.append(childTextNode.data)
00278 if ignoreEmtpyStringFragments:
00279 elementValueList = filter (lambda s: collapseString(s) != "", elementValueList)
00280 if elementValueList == []:
00281 elementValueList = ["",]
00282 return elementValueList
00283
00284
00285 def xmlIfExtGetElementText (self):
00286 elementTextList = ["",]
00287 if self.element.childNodes != []:
00288 for childNode in self.element.childNodes:
00289 if childNode.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
00290 elementTextList.append (childNode.data)
00291 else:
00292 break
00293 return "".join(elementTextList)
00294
00295
00296 def xmlIfExtGetElementTailText (self):
00297 tailTextList = ["",]
00298 nextSib = self.element.nextSibling
00299 while nextSib:
00300 if nextSib.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
00301 tailTextList.append (nextSib.data)
00302 nextSib = nextSib.nextSibling
00303 else:
00304 break
00305 return "".join(tailTextList)
00306
00307
00308 def xmlIfExtSetElementValue (self, elementValue):
00309 if self.__xmlIfExtGetChildTextNodes() == []:
00310 textNode = self.internalDomTreeWrapper.xmlIfExtCreateTextNode (elementValue)
00311 self.element.appendChild (textNode)
00312 else:
00313 self.__xmlIfExtGetChildTextNodes()[0].data = elementValue
00314 if len (self.__xmlIfExtGetChildTextNodes()) > 1:
00315 for textNode in self.__xmlIfExtGetChildTextNodes()[1:]:
00316 textNode.data = ""
00317
00318
00319 def xmlIfExtProcessWsElementValue (self, wsAction):
00320 textNodes = self.__xmlIfExtGetChildTextNodes()
00321
00322 if len(textNodes) == 1:
00323 textNodes[0].data = processWhitespaceAction (textNodes[0].data, wsAction)
00324 elif len(textNodes) > 1:
00325 textNodes[0].data = processWhitespaceAction (textNodes[0].data, wsAction, rstrip=0)
00326 lstrip = 0
00327 if len(textNodes[0].data) > 0 and textNodes[0].data[-1] == " ":
00328 lstrip = 1
00329 for textNode in textNodes[1:-1]:
00330 textNode.data = processWhitespaceAction (textNode.data, wsAction, lstrip, rstrip=0)
00331 if len(textNode.data) > 0 and textNode.data[-1] == " ":
00332 lstrip = 1
00333 else:
00334 lstrip = 0
00335 textNodes[-1].data = processWhitespaceAction (textNodes[-1].data, wsAction, lstrip)
00336
00337
00338
00339
00340
00341
00342 def __xmlIfExtGetChildTextNodes ( self ):
00343 """Return list of TEXT nodes."""
00344 return filter (lambda e: ( e.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE) ),
00345 self.element.childNodes)
00346
00347
00348
00349 class XmlIfBuilderExtensionDom (XmlIfBuilderExtensionBase):
00350 """XmlIf builder extension class for DOM parsers."""
00351
00352 pass