Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 45cd9de

Browse files
committed
Paul Prescod <[email protected]>:
SAX interfaces for Python.
1 parent 0d800e1 commit 45cd9de

5 files changed

Lines changed: 960 additions & 0 deletions

File tree

Lib/xml/sax/_exceptions.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""Different kinds of SAX Exceptions"""
2+
import sys
3+
if sys.platform[:4] == "java":
4+
from java.lang import Exception
5+
6+
# ===== SAXEXCEPTION =====
7+
8+
class SAXException(Exception):
9+
"""Encapsulate an XML error or warning. This class can contain
10+
basic error or warning information from either the XML parser or
11+
the application: you can subclass it to provide additional
12+
functionality, or to add localization. Note that although you will
13+
receive a SAXException as the argument to the handlers in the
14+
ErrorHandler interface, you are not actually required to throw
15+
the exception; instead, you can simply read the information in
16+
it."""
17+
18+
def __init__(self, msg, exception = None):
19+
"""Creates an exception. The message is required, but the exception
20+
is optional."""
21+
self._msg = msg
22+
self._exception = exception
23+
24+
def getMessage(self):
25+
"Return a message for this exception."
26+
return self._msg
27+
28+
def getException(self):
29+
"Return the embedded exception, or None if there was none."
30+
return self._exception
31+
32+
def __str__(self):
33+
"Create a string representation of the exception."
34+
return self._msg
35+
36+
def __getitem__(self, ix):
37+
"""Avoids weird error messages if someone does exception[ix] by
38+
mistake, since Exception has __getitem__ defined."""
39+
raise NameError("__getitem__")
40+
41+
42+
# ===== SAXPARSEEXCEPTION =====
43+
44+
class SAXParseException(SAXException):
45+
"""Encapsulate an XML parse error or warning.
46+
47+
This exception will include information for locating the error in
48+
the original XML document. Note that although the application will
49+
receive a SAXParseException as the argument to the handlers in the
50+
ErrorHandler interface, the application is not actually required
51+
to throw the exception; instead, it can simply read the
52+
information in it and take a different action.
53+
54+
Since this exception is a subclass of SAXException, it inherits
55+
the ability to wrap another exception."""
56+
57+
def __init__(self, msg, exception, locator):
58+
"Creates the exception. The exception parameter is allowed to be None."
59+
SAXException.__init__(self, msg, exception)
60+
self._locator = locator
61+
62+
def getColumnNumber(self):
63+
"""The column number of the end of the text where the exception
64+
occurred."""
65+
return self._locator.getColumnNumber()
66+
67+
def getLineNumber(self):
68+
"The line number of the end of the text where the exception occurred."
69+
return self._locator.getLineNumber()
70+
71+
def getPublicId(self):
72+
"Get the public identifier of the entity where the exception occurred."
73+
return self._locator.getPublicId()
74+
75+
def getSystemId(self):
76+
"Get the system identifier of the entity where the exception occurred."
77+
return self._locator.getSystemId()
78+
79+
def __str__(self):
80+
"Create a string representation of the exception."
81+
return "%s at %s:%d:%d" % (self._msg,
82+
self.getSystemId(),
83+
self.getLineNumber(),
84+
self.getColumnNumber())
85+
86+
87+
# ===== SAXNOTRECOGNIZEDEXCEPTION =====
88+
89+
class SAXNotRecognizedException(SAXException):
90+
"""Exception class for an unrecognized identifier.
91+
92+
An XMLReader will raise this exception when it is confronted with an
93+
unrecognized feature or property. SAX applications and extensions may
94+
use this class for similar purposes."""
95+
96+
97+
# ===== SAXNOTSUPPORTEDEXCEPTION =====
98+
99+
class SAXNotSupportedException(SAXException):
100+
"""Exception class for an unsupported operation.
101+
102+
An XMLReader will raise this exception when a service it cannot
103+
perform is requested (specifically setting a state or value). SAX
104+
applications and extensions may use this class for similar
105+
purposes."""
106+
107+
108+

Lib/xml/sax/expatreader.py

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
"""
2+
SAX driver for the Pyexpat C module. This driver works with
3+
pyexpat.__version__ == '1.5'.
4+
5+
$Id$
6+
"""
7+
8+
# Todo on driver:
9+
# - make it support external entities (wait for pyexpat.c)
10+
# - enable configuration between reset() and feed() calls
11+
# - support lexical events?
12+
# - proper inputsource handling
13+
# - properties and features
14+
15+
# Todo on pyexpat.c:
16+
# - support XML_ExternalEntityParserCreate
17+
# - exceptions in callouts from pyexpat to python code lose position info
18+
19+
version = "0.20"
20+
21+
from string import split
22+
23+
from xml.sax import xmlreader
24+
import pyexpat
25+
import xml.sax
26+
27+
# --- ExpatParser
28+
29+
class ExpatParser( xmlreader.IncrementalParser, xmlreader.Locator ):
30+
"SAX driver for the Pyexpat C module."
31+
32+
def __init__(self, namespaceHandling=0, bufsize=2**16-20):
33+
xmlreader.IncrementalParser.__init__(self, bufsize)
34+
self._source = None
35+
self._parser = None
36+
self._namespaces = namespaceHandling
37+
self._parsing = 0
38+
39+
# XMLReader methods
40+
41+
def parse(self, stream_or_string ):
42+
"Parse an XML document from a URL."
43+
if type( stream_or_string ) == type( "" ):
44+
stream=open( stream_or_string )
45+
else:
46+
stream=stream_or_string
47+
48+
self.reset()
49+
self._cont_handler.setDocumentLocator(self)
50+
try:
51+
xmlreader.IncrementalParser.parse(self, stream)
52+
except pyexpat.error:
53+
error_code = self._parser.ErrorCode
54+
raise xml.sax.SAXParseException(pyexpat.ErrorString(error_code),
55+
None, self)
56+
57+
self._cont_handler.endDocument()
58+
59+
def prepareParser(self, filename=None):
60+
self._source = filename
61+
62+
if self._source != None:
63+
self._parser.SetBase(self._source)
64+
65+
def getFeature(self, name):
66+
"Looks up and returns the state of a SAX2 feature."
67+
raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
68+
69+
def setFeature(self, name, state):
70+
"Sets the state of a SAX2 feature."
71+
raise SAXNotRecognizedException("Feature '%s' not recognized" % name)
72+
73+
def getProperty(self, name):
74+
"Looks up and returns the value of a SAX2 property."
75+
raise SAXNotRecognizedException("Property '%s' not recognized" % name)
76+
77+
def setProperty(self, name, value):
78+
"Sets the value of a SAX2 property."
79+
raise SAXNotRecognizedException("Property '%s' not recognized" % name)
80+
81+
# IncrementalParser methods
82+
83+
def feed(self, data):
84+
if not self._parsing:
85+
self._parsing=1
86+
self.reset()
87+
self._cont_handler.startDocument()
88+
# FIXME: error checking and endDocument()
89+
self._parser.Parse(data, 0)
90+
91+
def close(self):
92+
if self._parsing:
93+
self._cont_handler.endDocument()
94+
self._parsing=0
95+
self._parser.Parse("", 1)
96+
97+
def reset(self):
98+
if self._namespaces:
99+
self._parser = pyexpat.ParserCreate(None, " ")
100+
self._parser.StartElementHandler = self.start_element_ns
101+
self._parser.EndElementHandler = self.end_element_ns
102+
else:
103+
self._parser = pyexpat.ParserCreate()
104+
self._parser.StartElementHandler = self._cont_handler.startElement
105+
self._parser.EndElementHandler = self._cont_handler.endElement
106+
107+
self._parser.ProcessingInstructionHandler = \
108+
self._cont_handler.processingInstruction
109+
self._parser.CharacterDataHandler = self._cont_handler.characters
110+
self._parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl
111+
self._parser.NotationDeclHandler = self.notation_decl
112+
self._parser.StartNamespaceDeclHandler = self.start_namespace_decl
113+
self._parser.EndNamespaceDeclHandler = self.end_namespace_decl
114+
# self._parser.CommentHandler =
115+
# self._parser.StartCdataSectionHandler =
116+
# self._parser.EndCdataSectionHandler =
117+
# self._parser.DefaultHandler =
118+
# self._parser.DefaultHandlerExpand =
119+
# self._parser.NotStandaloneHandler =
120+
self._parser.ExternalEntityRefHandler = self.external_entity_ref
121+
122+
# Locator methods
123+
124+
def getColumnNumber(self):
125+
return self._parser.ErrorColumnNumber
126+
127+
def getLineNumber(self):
128+
return self._parser.ErrorLineNumber
129+
130+
def getPublicId(self):
131+
return self._source.getPublicId()
132+
133+
def getSystemId(self):
134+
return self._parser.GetBase()
135+
136+
# internal methods
137+
138+
# event handlers
139+
140+
def start_element(self, name, attrs):
141+
self._cont_handler.startElement(name,
142+
xmlreader.AttributesImpl(attrs, attrs))
143+
144+
def end_element(self, name):
145+
self._cont_handler.endElement(name)
146+
147+
def start_element_ns(self, name, attrs):
148+
pair = split(name)
149+
if len(pair) == 1:
150+
tup = (None, name, None)
151+
else:
152+
tup = pair+[None] # prefix is not implemented yet!
153+
154+
self._cont_handler.startElement(tup,
155+
xmlreader.AttributesImpl(attrs, None))
156+
157+
def end_element_ns(self, name):
158+
pair = split(name)
159+
if len(pair) == 1:
160+
name = (None, name, None)
161+
else:
162+
name = pair+[None] # prefix is not implemented yet!
163+
164+
self._cont_handler.endElement(name)
165+
166+
def processing_instruction(self, target, data):
167+
self._cont_handler.processingInstruction(target, data)
168+
169+
def character_data(self, data):
170+
self._cont_handler.characters(data)
171+
172+
def start_namespace_decl(self, prefix, uri):
173+
self._cont_handler.startPrefixMapping(prefix, uri)
174+
175+
def end_namespace_decl(self, prefix):
176+
self._cont_handler.endPrefixMapping(prefix)
177+
178+
def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
179+
self._dtd_handler.unparsedEntityDecl(name, pubid, sysid, notation_name)
180+
181+
def notation_decl(self, name, base, sysid, pubid):
182+
self._dtd_handler.notationDecl(name, pubid, sysid)
183+
184+
def external_entity_ref(self, context, base, sysid, pubid):
185+
assert 0 # not implemented
186+
source = self._ent_handler.resolveEntity(pubid, sysid)
187+
source = saxutils.prepare_input_source(source)
188+
# FIXME: create new parser, stack self._source and self._parser
189+
# FIXME: reuse code from self.parse(...)
190+
return 1
191+
192+
# ---
193+
194+
def create_parser(*args, **kwargs):
195+
return apply( ExpatParser, args, kwargs )
196+
197+
# ---
198+
199+
if __name__ == "__main__":
200+
import xml.sax
201+
p = create_parser()
202+
p.setContentHandler(xml.sax.XMLGenerator())
203+
p.setErrorHandler(xml.sax.ErrorHandler())
204+
p.parse("../../../hamlet.xml")

0 commit comments

Comments
 (0)