Viewing file: SaxWriter.py (7.36 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # $Header: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/SaxWriter.py,v 1.9 2005/03/18 23:47:19 jkloth Exp $ """ SAX2 event writer for XSLT output
Copyright 2005 Fourthought, Inc. (USA). Detailed license and copyright information: http://4suite.org/COPYRIGHT Project home, documentation, distributions: http://4suite.org/ """
import os
from Ft.Xml import EMPTY_NAMESPACE, XMLNS_NAMESPACE from Ft.Xml import CheckVersion from Ft.Xml.Domlette import implementation from Ft.Xml.Lib.XmlString import IsXmlSpace, SplitQName from Ft.Xml.XPath import Util from Ft.Xml.Xslt import XSL_NAMESPACE, TextSax from Ft.Xml.Xslt import OutputParameters
class ElementData: def __init__(self, name, attrs, extraNss=None): self.name = name self.attrs = attrs self.extraNss = extraNss or {}
try: from xml.dom.ext.reader import Sax, Sax2, HtmlSax except ImportError: #It will be caught if a SaxWriter is created pass
class SaxWriter: """ Requires PyXML (will be checked at instantiation time). """ def __init__(self, outputParams, saxHandler=None, fragment=False): CheckVersion(feature="4XSLT's SaxWriter") self.__fragment = fragment self.__firstElementFlag = True self.__orphanedNodes = [] self.__saxHandlerClass = None self.__saxHandler = None self.__stateStack = [] self.__currElement = None self.__currText = u'' self._outputParams = outputParams or OutputParameters.OutputParameters() if saxHandler: self.__saxHandler = saxHandler elif self.__outputParams.method == 'xml': self.__initSaxHandler(Sax2.XmlDomGenerator) if self.__outputParams.omitXmlDeclaration in [None, 'no']: self.__saxHandler.xmlDecl( self.__outputParams.version, self.__outputParams.encoding, self.__outputParams.standalone ) elif self.__outputParams.method == 'html': self.__initSaxHandler(HtmlSax.HtmlDomGenerator) elif self.__outputParams.method == 'text': self.__initSaxHandler(TextSax.TextGenerator)
def startDocument(self): return
def endDocument(self): return
def complete(self): return self.__saxHandler and self.__saxHandler.getRootNode() or None
def getResult(self): self.__completeTextNode() return self.__saxHandler.getRootNode()
def __initSaxHandler(self, saxHandlerClass): self.__saxHandlerClass = saxHandlerClass self.__saxHandler = saxHandlerClass(keepAllWs=1) for o_node in self.__orphanedNodes: if o_node[0] == 'pi': self.__saxHandler.processingInstruction(o_node[1], o_node[2]) elif o_node[0] == 'comment': self.__saxHandler.comment(o_node[1]) del self.__orphanedNodes return
def __initSax2Doc(self, doctype): self.__firstElementFlag = False if not self.__fragment: if not self.__saxHandler: self.__initSaxHandler(Sax2.XmlDomGenerator) if self.__outputParams.omitXmlDeclaration in [None, 'no']: self.__saxHandler.xmlDecl( self.__outputParams.version, self.__outputParams.encoding, self.__outputParams.standalone ) self.__saxHandler.startDTD(doctype, self.__outputParams.doctypeSystem, self.__outputParams.doctypePublic) self.__saxHandler.endDTD() return
def __initHtmlSaxDoc(self, doctype): self.__firstElementFlag = False if not self.__saxHandler: self.__initSaxHandler(HtmlSax.HtmlDomGenerator) #self.__saxHandler._4dom_startDTD(doctype, self.__outputParams.doctypeSystem, self.__outputParams.doctypePublic) #self.__saxHandler.endDTD()
def __completeTextNode(self): #FIXME: This does not allow multiple root nodes, which is required to be supported if self.__currText: if IsXmlSpace(self.__currText): self.__saxHandler.ignorableWhitespace(self.__currText) else: self.__saxHandler.characters(self.__currText) self.__currText = u'' return
def startElement(self, name, namespace=EMPTY_NAMESPACE, extraNss=None): extraNss = extraNss or {} attrs = {} if self.__firstElementFlag: if not self.__outputParams.method: if not namespace and name.upper() == 'HTML': self.__outputParams.method = 'html' else: self.__outputParams.method = 'xml' if self.__outputParams.method == 'xml': self.__initSax2Doc(name) else: self.__initHtmlSaxDoc(name) self.__firstElementFlag = False self.__completeTextNode() if self.__currElement: self.__saxHandler.startElement(self.__currElement.name, self.__currElement.attrs) self.__currElement = None self.__currElement = ElementData(name, attrs, extraNss) if self.__outputParams.method == 'xml': if namespace: (prefix, local) = SplitQName(name) if prefix: self.__currElement.attrs["xmlns:"+prefix] = namespace else: self.__currElement.attrs["xmlns"] = namespace for prefix in extraNss.keys(): if prefix: new_element.setAttributeNS(XMLNS_NAMESPACE, u'xmlns:'+prefix, extraNss[prefix]) else: new_element.setAttributeNS(XMLNS_NAMESPACE, u'xmlns', extraNss['']) return
def endElement(self, name): self.__completeTextNode() if self.__currElement: self.__saxHandler.startElement( self.__currElement.name, self.__currElement.attrs ) self.__currElement = None self.__saxHandler.endElement(name) return
def text(self, text, escapeOutput=True): if self.__currElement: self.__saxHandler.startElement( self.__currElement.name, self.__currElement.attrs ) self.__currElement = None self.__saxHandler.characters(text) return
def attribute(self, name, value, namespace=EMPTY_NAMESPACE): self.__currElement.attrs[name] = value if namespace: (prefix, local) = SplitQName(name) if prefix: self.__currElement.attrs[u"xmlns:"+prefix] = namespace return
def processingInstruction(self, target, data): self.__completeTextNode() if self.__saxHandler: self.__saxHandler.processingInstruction(target, data) else: self.__orphanedNodes.append(('pi', target, data)) return
def comment(self, body): self.__completeTextNode() if self.__saxHandler: self.__saxHandler.comment(body) else: self.__orphanedNodes.append(('comment', body)) return
|