/[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 1268 - (show annotations)
Fri Jun 20 16:10:12 2003 UTC (21 years, 8 months ago) by bh
Original Path: trunk/thuban/test/xmlsupport.py
File MIME type: text/x-python
File size: 5263 byte(s)
* Resources/XML/thuban-0.8.dtd: New DTD for the new file format
version.

* Thuban/Model/save.py (sort_data_stores): New. Make topological
sort of the data sources so they can be written with sources that
data sources that depend on other data sources come after the
sources they depend on.
(SessionSaver.__init__): Add idmap instance variable to map from
objects to the ids used in the file.
(SessionSaver.get_id, SessionSaver.define_id)
(SessionSaver.has_id): New. Methods to manage the idmap
(SessionSaver.write): Use thuban-0.8.dtd
(SessionSaver.write_session): Add a namespace on the session and
write out the data sources before the maps.
(SessionSaver.write_data_containers): New. Write the data
containers.
(SessionSaver.write_layer): Layer elements now refer to a
shapestore and don't contain filenames anymore.

* Thuban/Model/load.py (LoadError): Exception class to raise when
errors in the files are discovered
(SessionLoader.__init__): Define dispatchers for elements with a
thuban-0.8 namespace too.
(SessionLoader.check_attrs): New helper method to check and
convert attributes
(AttrDesc): New. Helper class for SessionLoader.check_attrs
(SessionLoader.start_fileshapesource)
(SessionLoader.start_derivedshapesource)
(SessionLoader.start_filetable, SessionLoader.start_jointable):
Handlers for the new elements in the new fileformat
(SessionLoader.start_layer): Handle the shapestore attribute in
addition to filename.
(SessionLoader.start_table, SessionLoader.end_table): Removed.
They were never used in the old formats and aren't needed for the
new.

* Thuban/Model/session.py (Session.DataContainers): New method to
return all "data containers", i.e. shapestores and tables

* test/xmlsupport.py (SaxEventLister.__init__)
(SaxEventLister.startElementNS, sax_eventlist): Add support to
normalize IDs.

* test/test_xmlsupport.py
(TestEventList.test_even_list_id_normalization): New test case for
id normalization

* test/test_load.py (LoadSessionTest.check_format): Use ID
normalization
(LoadSessionTest.thubanids, LoadSessionTest.thubanidrefs): New
class atrributes used for ID normalization
(TestSingleLayer, TestLayerVisibility, TestLabels.test)
(TestLayerProjection.test, TestRasterLayer.test): Adapt to new
file format
(TestJoinedTable): New test for loading sessions with joined
tables.
(TestLoadError): New. Test whether missing required attributes
cause a LoadError.

* test/test_save.py (SaveSessionTest.thubanids)
(SaveSessionTest.thubanidrefs): New class attributes for ID
normalization in .thuban files.
(SaveSessionTest.compare_xml): Use id-normalization.
(SaveSessionTest.testEmptySession)
(SaveSessionTest.testLayerProjection)
(SaveSessionTest.testRasterLayer)
(SaveSessionTest.testClassifiedLayer): Adapt to new file format.
(SaveSessionTest.testLayerProjection): The filename used was the
same as for testSingleLayer. Use a different one.
(SaveSessionTest.test_dbf_table)
(SaveSessionTest.test_joined_table): New test cases for saving the
new data sources structures.
(TestStoreSort, MockDataStore): Classes to test the sorting of the
data stores for writing.

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