/[thuban]/branches/WIP-pyshapelib-bramz/test/xmlsupport.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/test/xmlsupport.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 5821 byte(s)
made a copy
1 # Copyright (C) 2003 by Intevation GmbH
2 # Authors:
3 # Bernhard Herzog <[email protected]>
4 #
5 # This program is free software under the GPL (>=v2)
6 # Read the file COPYING coming with the software for details.
7
8 """XML support code for the test cases"""
9
10 __version__ = "$Revision$"
11 # $Source$
12 # $Id$
13
14 import sys
15 import os
16 from StringIO import StringIO
17 import xml.sax
18 import xml.sax.handler
19 from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException
20
21 import support
22
23 try:
24 import pyRXP
25 except ImportError:
26 pyRXP = None
27
28 class ValidationTest:
29
30 """Mix-in class for tests that want to check for validity of XML data"""
31
32 # If true, at least one test case tried to validate XML data but
33 # couldn't because PyRXP is not available
34 validation_attempt_ignored = False
35
36 def validate_data(self, data):
37 """Validate the XML data"""
38 if pyRXP is not None:
39 parser = pyRXP.Parser()
40 try:
41 parser.parse(data, eoCB = self.rxp_eo_cb)
42 except pyRXP.error, val:
43 raise AssertionError, str(val), sys.exc_info()[2]
44 else:
45 ValidationTest.validation_attempt_ignored = True
46
47 def rxp_eo_cb(self, filename):
48 """Resolve an eternal entity
49
50 In the Thuban test cases the only external entities that have to
51 be resolved are the DTDs which now live in the resource
52 directory. So, interpret any filename relative to that
53 directory.
54 """
55 return os.path.join(support.resource_dir(), "XML", filename)
56
57
58 #
59 # Classes and functions to convert XML to a normalized list
60 # representation for comparisons
61 #
62
63 class SaxEventLister(xml.sax.handler.ContentHandler):
64
65 """Create a normalized list representation containing the SAX events
66
67 The normalization includes the following
68
69 - The attribute dictionary of a staertElement event is converted to
70 a sorted list of (key, value) pairs
71
72 - ID and IDREF attribute values are normalized in such a way that
73 two documents that only use different values for IDs can still
74 lead to the same normalized representation.
75
76 The implementation of this feature assumes that all IDs are
77 defined before they are used. The normalized ID values are of the
78 form 'D<NUM>' where <NUM> is a counter starting with 0, so the
79 first ID value will become 'D0', the second 'D1', etc.
80
81 Which attributes are IDs or IDREFS is defined with the
82 correspoding constructor arguments.
83
84 - Filenames are normalized with os.path.normpath. Which attributes
85 are filenames is defiend with the corresponding constructor
86 argument.
87 """
88
89 def __init__(self, ids = (), idrefs = (), filenames = ()):
90 """Initialize the SaxEventLister
91
92 The ids and idrefs parameters should be lists of (element, attr)
93 pairs where element is the name of an attribute as passed to the
94 startElementNS method and attr is the name of an attribute as
95 used in the mapping passed to startElementNS, so both name and
96 attr usually must include the namespace.
97
98 The filenames parameter should be a sequence of the same form as
99 ids and idrefs identifying the attributes which are filenames
100 that should be normalized.
101 """
102 self.eventlist = []
103 self.ids = ids
104 self.idrefs = idrefs
105 self.idremap = {}
106 self.filenames = filenames
107
108 def startElementNS(self, name, qname, attrs):
109 items = attrs.items()
110 items.sort()
111 for i, (attr, value) in zip(range(len(items)), items):
112 #print '++++'
113 #print self.idremap
114 #print name, attr, value
115 if (name, attr) in self.ids:
116 newid = len(self.idremap)
117 self.idremap[value] = "D" + str(newid)
118 value = self.idremap[value]
119 elif (name, attr) in self.idrefs:
120 value = self.idremap[value]
121 elif (name, attr) in self.filenames:
122 value = os.path.normpath(value)
123 items[i] = (attr, value)
124 #print name, attr, value
125 self.eventlist.append(("start", name, items))
126
127 def endElementNS(self, name, qname):
128 self.eventlist.append(("end", name))
129
130
131 def sax_eventlist(data = None, filename = None,
132 ids = (), idrefs = (), filenames = ()):
133 """Return a list of SAX event generated for a given XML source
134
135 The xml source may either be a string with the actual XML, in which
136 case it should be given as the keyword argument data or the name of
137 an xml file given as the keyword argument filename
138 """
139 if filename is not None:
140 data = open(filename).read()
141 handler = SaxEventLister(ids = ids, idrefs = idrefs, filenames = filenames)
142 parser = make_parser()
143 parser.setContentHandler(handler)
144 parser.setErrorHandler(ErrorHandler())
145 parser.setFeature(xml.sax.handler.feature_namespaces, 1)
146
147 #
148 # see comment at the end of Thuban/Model/load.py
149 #
150 try:
151 parser.setFeature(xml.sax.handler.feature_validation, 0)
152 parser.setFeature(xml.sax.handler.feature_external_ges, 0)
153 parser.setFeature(xml.sax.handler.feature_external_pes, 0)
154 except SAXNotRecognizedException:
155 pass
156
157 inpsrc = xml.sax.InputSource()
158 inpsrc.setByteStream(StringIO(data))
159 parser.parse(inpsrc)
160
161 return handler.eventlist
162
163
164 def print_summary_message():
165 """Print a summary message about validation tests
166
167 Currently simply print a message about pyRXP not being available if
168 a test case's attempt to validate XML was ignored because of that.
169 """
170 if ValidationTest.validation_attempt_ignored:
171 print "XML validation attempts ignored because pyRXP is not available"

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26