Kaydet (Commit) a13a9dcb authored tarafından Martin v. Löwis's avatar Martin v. Löwis

Use SAX2 namespace support.

üst a4287c29
import minidom import minidom
import xml.sax import xml.sax,xml.sax.handler
#todo: namespace handling
START_ELEMENT = "START_ELEMENT" START_ELEMENT = "START_ELEMENT"
END_ELEMENT = "END_ELEMENT" END_ELEMENT = "END_ELEMENT"
...@@ -12,22 +10,44 @@ PROCESSING_INSTRUCTION = "PROCESSING_INSTRUCTION" ...@@ -12,22 +10,44 @@ PROCESSING_INSTRUCTION = "PROCESSING_INSTRUCTION"
IGNORABLE_WHITESPACE = "IGNORABLE_WHITESPACE" IGNORABLE_WHITESPACE = "IGNORABLE_WHITESPACE"
CHARACTERS = "CHARACTERS" CHARACTERS = "CHARACTERS"
class PullDOM: class PullDOM(xml.sax.ContentHandler):
def __init__(self): def __init__(self):
self.firstEvent = [None, None] self.firstEvent = [None, None]
self.lastEvent = self.firstEvent self.lastEvent = self.firstEvent
self._ns_contexts = [{}] # contains uri -> prefix dicts
self._current_context = self._ns_contexts[-1]
def setDocumentLocator(self, locator): pass def setDocumentLocator(self, locator): pass
def startElement(self, name, attrs): def startPrefixMapping(self, prefix, uri):
if not hasattr(self, "curNode"): self._ns_contexts.append(self._current_context.copy())
# FIXME: hack! self._current_context[uri] = prefix
self.startDocument()
def endPrefixMapping(self, prefix):
node = self.document.createElement(name) del self._ns_contexts[-1]
for (attr, value) in attrs.items():
node.setAttribute(attr, attrs[attr]) def startElementNS(self, name, tagName , attrs):
if name[0]:
# When using namespaces, the reader may or may not
# provide us with the original name. If not, create
# *a* valid tagName from the current context.
if tagName is None:
tagName = self._current_context[name[0]] + ":" + name[1]
node = self.document.createElementNS(name[0], tagName)
else:
# When the tagname is not prefixed, it just appears as
# name[1]
node = self.document.createElement(name[1])
for aname,value in attrs.items():
if aname[0]:
qname = self._current_context[name[0]] + ":" + aname[1]
attr = self.document.createAttributeNS(name[0], qname)
else:
attr = self.document.createAttribute(name[0], name[1])
attr.value = value
node.setAttributeNode(qname, attr)
parent = self.curNode parent = self.curNode
node.parentNode = parent node.parentNode = parent
if parent.childNodes: if parent.childNodes:
...@@ -39,7 +59,7 @@ class PullDOM: ...@@ -39,7 +59,7 @@ class PullDOM:
self.lastEvent = self.lastEvent[1] self.lastEvent = self.lastEvent[1]
#self.events.append((START_ELEMENT, node)) #self.events.append((START_ELEMENT, node))
def endElement(self, name): def endElementNS(self, name, tagName):
node = self.curNode node = self.curNode
self.lastEvent[1] = [(END_ELEMENT, node), None] self.lastEvent[1] = [(END_ELEMENT, node), None]
self.lastEvent = self.lastEvent[1] self.lastEvent = self.lastEvent[1]
...@@ -122,6 +142,8 @@ class DOMEventStream: ...@@ -122,6 +142,8 @@ class DOMEventStream:
def reset(self): def reset(self):
self.pulldom = PullDOM() self.pulldom = PullDOM()
# This content handler relies on namespace support
self.parser.setFeature(xml.sax.handler.feature_namespaces,1)
self.parser.setContentHandler(self.pulldom) self.parser.setContentHandler(self.pulldom)
def __getitem__(self, pos): def __getitem__(self, pos):
...@@ -154,18 +176,6 @@ class DOMEventStream: ...@@ -154,18 +176,6 @@ class DOMEventStream:
self.pulldom.firstEvent[1] = self.pulldom.firstEvent[1][1] self.pulldom.firstEvent[1] = self.pulldom.firstEvent[1][1]
return rc return rc
# FIXME: sax2
#def _getParser( ):
# from xml.sax.saxexts import make_parser
# expat doesn't report errors properly! Figure it out
# return make_parser()
# return make_parser("xml.sax.drivers.drv_xmllib")
def _getParser():
return xml.sax.make_parser()
default_bufsize = (2 ** 14) - 20 default_bufsize = (2 ** 14) - 20
# FIXME: move into sax package for common usage # FIXME: move into sax package for common usage
...@@ -175,7 +185,7 @@ def parse(stream_or_string, parser=None, bufsize=default_bufsize): ...@@ -175,7 +185,7 @@ def parse(stream_or_string, parser=None, bufsize=default_bufsize):
else: else:
stream = stream_or_string stream = stream_or_string
if not parser: if not parser:
parser = _getParser() parser = xml.sax.make_parser()
return DOMEventStream(stream, parser, bufsize) return DOMEventStream(stream, parser, bufsize)
def parseString(string, parser=None): def parseString(string, parser=None):
...@@ -186,5 +196,6 @@ def parseString(string, parser=None): ...@@ -186,5 +196,6 @@ def parseString(string, parser=None):
bufsize = len(string) bufsize = len(string)
buf = StringIO(string) buf = StringIO(string)
parser = _getParser() if not parser:
parser = xml.sax.make_parser()
return DOMEventStream(buf, parser, bufsize) return DOMEventStream(buf, parser, bufsize)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment