import pprint
import sys
from xml.dom import xmlbuilder, expatbuilder, Node
from xml.dom.NodeFilter import NodeFilter
class Filter(xmlbuilder.DOMBuilderFilter):
whatToShow = NodeFilter.SHOW_ELEMENT
def startContainer(self, node):
assert node.nodeType == Node.ELEMENT_NODE
if node.tagName == "skipthis":
return self.FILTER_SKIP
elif node.tagName == "rejectbefore":
return self.FILTER_REJECT
elif node.tagName == "stopbefore":
return self.FILTER_INTERRUPT
else:
return self.FILTER_ACCEPT
def acceptNode(self, node):
assert node.nodeType == Node.ELEMENT_NODE
if node.tagName == "skipafter":
return self.FILTER_SKIP
elif node.tagName == "rejectafter":
return self.FILTER_REJECT
elif node.tagName == "stopafter":
return self.FILTER_INTERRUPT
else:
return self.FILTER_ACCEPT
class RecordingFilter:
# Inheriting from xml.dom.xmlbuilder.DOMBuilderFilter is not
# required, so we won't inherit from it this time to make sure it
# isn't a problem. We have to implement the entire interface
# directly.
whatToShow = NodeFilter.SHOW_ALL
def __init__(self):
self.events = []
def startContainer(self, node):
self.events.append(("start", node.nodeType, str(node.nodeName)))
return xmlbuilder.DOMBuilderFilter.FILTER_ACCEPT
def acceptNode(self, node):
self.events.append(("accept", node.nodeType, str(node.nodeName)))
return xmlbuilder.DOMBuilderFilter.FILTER_ACCEPT
simple_options = xmlbuilder.Options()
simple_options.filter = Filter()
simple_options.namespaces = 0
record_options = xmlbuilder.Options()
record_options.namespaces = 0
def checkResult(src):
print
dom = expatbuilder.makeBuilder(simple_options).parseString(src)
print dom.toxml()
dom.unlink()
def checkFilterEvents(src, record, what=NodeFilter.SHOW_ALL):
record_options.filter = RecordingFilter()
record_options.filter.whatToShow = what
dom = expatbuilder.makeBuilder(record_options).parseString(src)
if record != record_options.filter.events:
print
print "Received filter events:"
pprint.pprint(record_options.filter.events)
print
print "Expected filter events:"
pprint.pprint(record)
dom.unlink()
# a simple case of skipping an element
checkResult("textmoreabcxyz")
# skip an element nested indirectly within another skipped element
checkResult('''\
Text.
Nested text.
Nested text in skipthis element.
More nested text.
Outer text.
''')
# skip an element nested indirectly within another skipped element
checkResult('''\
Text.
Nested text.
Nested text in skipthis element.
More nested text.
More text.
Outer text.
''')
checkResult("")
checkResult("")
checkResult('''\
Text.
''')
checkResult('''\
Text.
''')
# Make sure the document element is not passed to the filter:
checkResult("")
checkResult("")
checkResult("")
checkResult("text and more")
checkResult("text and more")
checkResult("text")
checkFilterEvents("", [])
checkFilterEvents("", [])
checkFilterEvents("", [
("start", Node.ELEMENT_NODE, "e"),
("accept", Node.ELEMENT_NODE, "e"),
])
src = """\
]>
"""
checkFilterEvents(src, [
("accept", Node.DOCUMENT_TYPE_NODE, "doc"),
("accept", Node.ENTITY_NODE, "e"),
("accept", Node.NOTATION_NODE, "n"),
("accept", Node.COMMENT_NODE, "#comment"),
("accept", Node.PROCESSING_INSTRUCTION_NODE, "sample"),
("start", Node.ELEMENT_NODE, "e"),
("accept", Node.PROCESSING_INSTRUCTION_NODE, "pi"),
("accept", Node.COMMENT_NODE, "#comment"),
("accept", Node.ELEMENT_NODE, "e"),
])
# Show everything except a couple of things to the filter, to check
# that whatToShow is implemented. This isn't sufficient to be a
# black-box test, but will get us started.
checkFilterEvents(src, [
("accept", Node.DOCUMENT_TYPE_NODE, "doc"),
("accept", Node.ENTITY_NODE, "e"),
("accept", Node.NOTATION_NODE, "n"),
("accept", Node.PROCESSING_INSTRUCTION_NODE, "sample"),
("start", Node.ELEMENT_NODE, "e"),
("accept", Node.PROCESSING_INSTRUCTION_NODE, "pi"),
("accept", Node.ELEMENT_NODE, "e"),
], what=NodeFilter.SHOW_ALL & ~NodeFilter.SHOW_COMMENT)
checkFilterEvents(src, [
("accept", Node.DOCUMENT_TYPE_NODE, "doc"),
("accept", Node.ENTITY_NODE, "e"),
("accept", Node.NOTATION_NODE, "n"),
("accept", Node.COMMENT_NODE, "#comment"),
("start", Node.ELEMENT_NODE, "e"),
("accept", Node.COMMENT_NODE, "#comment"),
("accept", Node.ELEMENT_NODE, "e"),
], what=NodeFilter.SHOW_ALL & ~NodeFilter.SHOW_PROCESSING_INSTRUCTION)