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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (hide 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 bh 1245 # 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 bh 1683 __version__ = "$Revision$"
11     # $Source$
12     # $Id$
13    
14 bh 1245 import sys
15     import os
16 bh 1257 from StringIO import StringIO
17     import xml.sax
18     import xml.sax.handler
19     from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException
20    
21 bh 1245 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 bh 1257 #
59     # Classes and functions to convert XML to a normalized list
60     # representation for comparisons
61     #
62 bh 1245
63 bh 1257 class SaxEventLister(xml.sax.handler.ContentHandler):
64    
65     """Create a normalized list representation containing the SAX events
66 bh 1268
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 bh 1683
84     - Filenames are normalized with os.path.normpath. Which attributes
85     are filenames is defiend with the corresponding constructor
86     argument.
87 bh 1257 """
88    
89 bh 1683 def __init__(self, ids = (), idrefs = (), filenames = ()):
90 bh 1268 """Initialize the SaxEventLister
91    
92     The ids and idrefs parameters should be lists of (element, attr)
93 bh 1683 pairs where element is the name of an attribute as passed to the
94 bh 1268 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 bh 1683
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 bh 1268 """
102 bh 1257 self.eventlist = []
103 bh 1268 self.ids = ids
104     self.idrefs = idrefs
105     self.idremap = {}
106 bh 1683 self.filenames = filenames
107 bh 1257
108     def startElementNS(self, name, qname, attrs):
109     items = attrs.items()
110     items.sort()
111 bh 1268 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 bh 1683 elif (name, attr) in self.filenames:
122     value = os.path.normpath(value)
123 bh 1268 items[i] = (attr, value)
124     #print name, attr, value
125 bh 1280 self.eventlist.append(("start", name, items))
126 bh 1257
127     def endElementNS(self, name, qname):
128 bh 1280 self.eventlist.append(("end", name))
129 bh 1257
130    
131 bh 1268 def sax_eventlist(data = None, filename = None,
132 bh 1683 ids = (), idrefs = (), filenames = ()):
133 bh 1257 """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 bh 1683 handler = SaxEventLister(ids = ids, idrefs = idrefs, filenames = filenames)
142 bh 1257 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 bh 1245 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