You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-lib/pym/calculate/contrib/suds/sax/parser.py

138 lines
4.1 KiB

# This program is free software; you can redistribute it and/or modify it under
# the terms of the (LGPL) GNU Lesser General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Library Lesser General Public License
# for more details at ( http://www.gnu.org/licenses/lgpl.html ).
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# written by: Jeff Ortel ( jortel@redhat.com )
"""
Classes providing a (D)ocument (O)bject (M)odel representation of an XML
document.
The goal is to provide an easy, intuitive interface for managing XML documents.
Although the term DOM is used above, this model is B{far} better.
XML namespaces in suds are represented using a (2) element tuple containing the
prefix and the URI, e.g. I{('tns', 'http://myns')}.
"""
import suds
from suds import *
from suds.sax import *
from suds.sax.attribute import Attribute
from suds.sax.document import Document
from suds.sax.element import Element
from suds.sax.text import Text
import sys
from xml.sax import make_parser, InputSource, ContentHandler
from xml.sax.handler import feature_external_ges
class Handler(ContentHandler):
"""SAX handler."""
def __init__(self):
self.nodes = [Document()]
def startElement(self, name, attrs):
top = self.top()
node = Element(str(name))
for a in attrs.getNames():
n = str(a)
v = str(attrs.getValue(a))
attribute = Attribute(n, v)
if self.mapPrefix(node, attribute):
continue
node.append(attribute)
node.charbuffer = []
top.append(node)
self.push(node)
def mapPrefix(self, node, attribute):
if attribute.name == "xmlns":
if len(attribute.value):
node.expns = str(attribute.value)
return True
if attribute.prefix == "xmlns":
prefix = attribute.name
node.nsprefixes[prefix] = str(attribute.value)
return True
return False
def endElement(self, name):
name = str(name)
current = self.pop()
if name != current.qname():
raise Exception("malformed document")
if current.charbuffer:
current.text = Text("".join(current.charbuffer))
del current.charbuffer
if current:
current.trim()
def characters(self, content):
text = str(content)
node = self.top()
node.charbuffer.append(text)
def push(self, node):
self.nodes.append(node)
return node
def pop(self):
return self.nodes.pop()
def top(self):
return self.nodes[-1]
class Parser:
"""SAX parser."""
@classmethod
def saxparser(cls):
p = make_parser()
p.setFeature(feature_external_ges, 0)
h = Handler()
p.setContentHandler(h)
return p, h
def parse(self, file=None, string=None):
"""
SAX parse XML text.
@param file: Parse a python I{file-like} object.
@type file: I{file-like} object
@param string: Parse string XML.
@type string: str
@return: Parsed XML document.
@rtype: L{Document}
"""
if file is None and string is None:
return
timer = suds.metrics.Timer()
timer.start()
source = file
if file is None:
source = InputSource(None)
source.setByteStream(suds.BytesIO(string))
sax, handler = self.saxparser()
sax.parse(source)
timer.stop()
if file is None:
suds.metrics.log.debug("%s\nsax duration: %s", string, timer)
else:
suds.metrics.log.debug("sax (%s) duration: %s", file, timer)
return handler.nodes[0]