Package suds :: Package sax :: Module parser
[hide private]
[frames] | no frames]

Source Code for Module suds.sax.parser

  1  # This program is free software; you can redistribute it and/or modify 
  2  # it under the terms of the (LGPL) GNU Lesser General Public License as 
  3  # published by the Free Software Foundation; either version 3 of the  
  4  # License, or (at your option) any later version. 
  5  # 
  6  # This program is distributed in the hope that it will be useful, 
  7  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  8  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  9  # GNU Library Lesser General Public License for more details at 
 10  # ( http://www.gnu.org/licenses/lgpl.html ). 
 11  # 
 12  # You should have received a copy of the GNU Lesser General Public License 
 13  # along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 15  # written by: Jeff Ortel ( jortel@redhat.com ) 
 16   
 17  """ 
 18  The sax module contains a collection of classes that provide a 
 19  (D)ocument (O)bject (M)odel representation of an XML document. 
 20  The goal is to provide an easy, intuative interface for managing XML 
 21  documents.  Although, the term, DOM, is used above, this model is 
 22  B{far} better. 
 23   
 24  XML namespaces in suds are represented using a (2) element tuple 
 25  containing the prefix and the URI.  Eg: I{('tns', 'http://myns')} 
 26   
 27  """ 
 28   
 29  from logging import getLogger 
 30  import suds.metrics 
 31  from suds import * 
 32  from suds.sax import * 
 33  from suds.sax.document import Document 
 34  from suds.sax.element import Element 
 35  from suds.sax.text import Text 
 36  from suds.sax.attribute import Attribute 
 37  from xml.sax import make_parser, InputSource, ContentHandler 
 38  from xml.sax.handler import feature_external_ges 
 39  from cStringIO import StringIO 
 40   
 41  log = getLogger(__name__) 
42 43 44 -class Handler(ContentHandler):
45 """ sax hanlder """ 46
47 - def __init__(self):
48 self.nodes = [Document()]
49
50 - def startElement(self, name, attrs):
51 top = self.top() 52 node = Element(unicode(name), parent=top) 53 for a in attrs.getNames(): 54 n = unicode(a) 55 v = unicode(attrs.getValue(a)) 56 attribute = Attribute(n,v) 57 if self.mapPrefix(node, attribute): 58 continue 59 node.append(attribute) 60 node.charbuffer = [] 61 top.append(node) 62 self.push(node)
63
64 - def mapPrefix(self, node, attribute):
65 skip = False 66 if attribute.name == 'xmlns': 67 if len(attribute.value): 68 node.expns = unicode(attribute.value) 69 skip = True 70 elif attribute.prefix == 'xmlns': 71 prefix = attribute.name 72 node.nsprefixes[prefix] = unicode(attribute.value) 73 skip = True 74 return skip
75
76 - def endElement(self, name):
77 name = unicode(name) 78 current = self.top() 79 if len(current.charbuffer): 80 current.text = Text(u''.join(current.charbuffer)) 81 del current.charbuffer 82 if len(current): 83 current.trim() 84 currentqname = current.qname() 85 if name == currentqname: 86 self.pop() 87 else: 88 raise Exception('malformed document')
89
90 - def characters(self, content):
91 text = unicode(content) 92 node = self.top() 93 node.charbuffer.append(text)
94
95 - def push(self, node):
96 self.nodes.append(node) 97 return node
98
99 - def pop(self):
100 return self.nodes.pop()
101
102 - def top(self):
103 return self.nodes[len(self.nodes)-1]
104
105 106 -class Parser:
107 """ SAX Parser """ 108 109 @classmethod
110 - def saxparser(cls):
111 p = make_parser() 112 p.setFeature(feature_external_ges, 0) 113 h = Handler() 114 p.setContentHandler(h) 115 return (p, h)
116
117 - def parse(self, file=None, string=None):
118 """ 119 SAX parse XML text. 120 @param file: Parse a python I{file-like} object. 121 @type file: I{file-like} object. 122 @param string: Parse string XML. 123 @type string: str 124 """ 125 timer = metrics.Timer() 126 timer.start() 127 sax, handler = self.saxparser() 128 if file is not None: 129 sax.parse(file) 130 timer.stop() 131 metrics.log.debug('sax (%s) duration: %s', file, timer) 132 return handler.nodes[0] 133 if string is not None: 134 source = InputSource(None) 135 source.setByteStream(StringIO(string)) 136 sax.parse(source) 137 timer.stop() 138 metrics.log.debug('%s\nsax duration: %s', string, timer) 139 return handler.nodes[0]
140