|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /proc/self/root/usr/lib/python2.4/site-packages/_xmlplus/xslt/ |
Upload File : |
########################################################################
#
# File Name: XmlWriter.py
#
#
"""
Implements the XML output writer for XSLT processor output
WWW: http://4suite.com/4XSLT e-mail: support@4suite.com
Copyright (c) 1999-2000 Fourthought Inc., USA. All Rights Reserved.
See http://4suite.com/COPYRIGHT for license and copyright information
"""
import os, re, string
import xml.dom.ext
from xml.dom.ext.Printer import TranslateCdata, TranslateCdataAttr
from xml.dom.html import TranslateHtmlCdata
from xml.xslt import XSL_NAMESPACE, NullWriter, XsltException, Error
from xml.dom.html import HTML_4_TRANSITIONAL_INLINE, HTML_4_STRICT_INLINE
from xml.dom import XML_NAMESPACE, EMPTY_NAMESPACE
from xml.dom.html import HTML_FORBIDDEN_END
class ElementData:
def __init__(self, name, cdataElement, attrs, extraNss=None):
self.name = name
self.cdataElement = cdataElement
self.attrs = attrs
self.extraNss = extraNss or {}
return
class XmlWriter(NullWriter.NullWriter):
def __init__(self, outputParams, stream=None):
NullWriter.NullWriter.__init__(self, outputParams, stream)
self._outputParams.encoding = outputParams.encoding or 'UTF-8'
self._outputParams.indent = outputParams.indent == 'yes'
self._outputParams.mediaType = outputParams.mediaType or 'text/xml'
self._currElement = None
self._namespaces = [{'': EMPTY_NAMESPACE, 'xml': XML_NAMESPACE}]
self._indent = ''
self._nextNewLine = 0
self._cdataSectionElement = 0
self._first_element = 1
self._cached = []
return
def _doctype(self, docElem):
external_id = ''
if self._outputParams.doctypePublic and self._outputParams.doctypeSystem:
external_id = ' PUBLIC "' + self._outputParams.doctypePublic + '" "' + self._outputParams.doctypeSystem + '"'
elif self._outputParams.doctypeSystem:
external_id = ' SYSTEM "' + self._outputParams.doctypeSystem + '"'
if external_id:
self._stream.write('<!DOCTYPE %s%s>\n' % (docElem, external_id))
self._first_element = 0
def startDocument(self):
if self._outputParams.omitXmlDeclaration in [None,'no']:
self._stream.write("<?xml version='%s' encoding='%s'" % (
self._outputParams.version,
self._outputParams.encoding))
if self._outputParams.standalone:
self._stream.write(" standalone='%s'" % self._outputParams.standalone)
self._stream.write("?>\n")
return
def endDocument(self):
self._completeLastElement(0)
return
def text(self, text, escapeOutput=1):
self._completeLastElement(0)
if escapeOutput:
if text and text[0] == '>':
self._stream.seek(-2, 2)
last_chars = self._stream.read()
else:
last_chars = ''
text = TranslateCdata(
text,
self._outputParams.encoding,
last_chars,
markupSafe=self._cdataSectionElement
)
self._stream.write(text)
self._nextNewLine = 0
return
def attribute(self, name, value, namespace=EMPTY_NAMESPACE):
if not self._currElement:
raise XsltException(Error.ATTRIBUTE_ADDED_AFTER_ELEMENT)
value = TranslateCdata(value, self._outputParams.encoding)
self._currElement.attrs[name] = TranslateCdataAttr(value)
(prefix, local) = xml.dom.ext.SplitQName(name)
self._namespaces[-1][prefix] = namespace
return
def processingInstruction(self, target, data):
self._completeLastElement(0)
target = string.strip(TranslateCdata(target, self._outputParams.encoding, ''))
data = string.strip(TranslateCdata(data, self._outputParams.encoding, ''))
pi = '<?%s %s?>' % (target, data)
if self._outputParams.indent:
self._stream.write("%s%s\n" % (self._indent, pi))
else:
self._stream.write(pi)
self._nextNewLine = 1
return
def comment(self, body):
self._completeLastElement(0)
body = TranslateCdata(body, self._outputParams.encoding, '')
comment = "<!--%s-->" % body
if self._outputParams.indent:
self._stream.write("%s%s\n" % (self._indent, comment))
else:
self._stream.write(comment)
self._nextNewLine = 1
return
def startElement(self, name, namespace=EMPTY_NAMESPACE, extraNss=None):
extraNss = extraNss or {}
self._completeLastElement(0)
if self._first_element:
self._doctype(name)
(prefix, local) = xml.dom.ext.SplitQName(name)
cdatas_flag = (namespace, local) in self._outputParams.cdataSectionElements
self._currElement = ElementData(name, cdatas_flag, {}, extraNss)
self._namespaces.append(self._namespaces[-1].copy())
self._namespaces[-1][prefix] = namespace
return
def endElement(self, name):
if self._currElement:
elementIsEmpty = 1
self._completeLastElement(1)
else:
elementIsEmpty = 0
if self._outputParams.indent:
self._indent = self._indent[:-2]
if self._cdataSectionElement:
self._stream.write(']]>')
self._cdataSectionElement = 0
if self._outputParams.indent and self._nextNewLine and not elementIsEmpty:
self._stream.write('\n' + self._indent)
self._stream.write((not elementIsEmpty) and ('</%s>' % name) or '')
self._nextNewLine = 1
del self._namespaces[-1]
return
def _completeLastElement(self, elementIsEmpty):
if self._currElement:
elem = self._currElement
if self._outputParams.indent and self._nextNewLine:
self._stream.write('\n' + self._indent)
self._stream.write('<' + elem.name)
for (name, (value, delimiter)) in elem.attrs.items():
self._stream.write(' %s=%s%s%s' % (name,delimiter,value,delimiter))
#Handle namespaces
nss = elem.extraNss
nss.update(self._namespaces[-1])
for prefix in nss.keys():
ns = nss[prefix]
prev_ns = self._namespaces[-2].get(prefix, None)
if ns and not prev_ns:
if prefix:
self._stream.write(" xmlns:%s='%s'" % (prefix, ns))
else:
self._stream.write(" xmlns='%s'" % ns)
self._namespaces[-1] = nss
if elementIsEmpty:
self._stream.write('/>')
else:
self._stream.write('>')
if self._currElement.cdataElement:
self._stream.write('<![CDATA[')
self._cdataSectionElement = 1
self._nextNewLine = 1
if self._outputParams.indent:
self._indent = self._indent + ' '
self._currElement = None
return