source: TI02-CSML/trunk/csml/parser_extra.py @ 4034

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/csml/parser_extra.py@4034
Revision 4034, 9.0 KB checked in by cbyrom, 12 years ago (diff)

Fix PrettyPrint? to cast elem data as string, before attempting to
call strip() on it (to avoid problems when handling, e.g. ints).
Add ndgmetadata1.3.xsd to csml package and extend molesReadWrite to
use this version, to avoid the need to having to copy this file
locally on each use.

Line 
1#parser_extra.py
2# DL 12 april 2006
3#v2 DL 22 November 2006: changed namespaces to reflect v2 schema
4# 'extra' functions to enable parsing.
5#contains:
6#. Namespace fix
7# Function to resolve references in CSML doc.
8
9import csml
10import csml.parser
11from csml.csmllibs.csmlextra import listify
12import sys
13
14#import ElementTree
15try: #python 2.5
16    from xml.etree import ElementTree as etree
17except ImportError:
18    try:
19        # if you've installed it yourself it comes this way
20        import ElementTree as etree
21    except ImportError:
22        # if you've egged it this is the way it comes
23        from elementtree import ElementTree as etree
24       
25
26#now import cElementTree
27try: #python 2.5
28    from xml.etree import cElementTree as ET
29except ImportError:
30    try:
31        # if you've installed it yourself it comes this way
32        import cElementTree as ET
33    except ImportError:
34        # if you've egged it this is the way it comes
35        from elementtree import cElementTree as ET
36       
37import string
38import codecs
39
40
41#some xml/string manipulation functions. may as well go in this file for now:
42
43def encodingParser(file, encoding):
44    f = codecs.open(file, "r", encoding)
45    p = ET.XMLParser(encoding="utf-8")
46    while 1:
47        s = f.read(65536)
48        if not s:
49            break
50        p.feed(s.encode("utf-8"))
51    return ET.ElementTree(p.close())
52
53
54def PrettyPrint(elem,indent='',html=0,space='   '):
55        '''Lightweight pretty printing of elementTree elements'''
56        def estrip(elem):
57                ''' Just want to get rid of unwanted whitespace '''
58                if elem is None:
59                        return ''
60                else:
61                        # just in case the elem is another simple type - e.g. int - wrapper it as a string
62                        return str(elem).strip()
63        strAttrib=''
64        for att in elem.attrib:
65                strAttrib+=' %s="%s"'%(att,elem.attrib[att])
66        result='%s<%s%s>%s'%(indent,elem.tag,strAttrib,estrip(elem.text))
67        children=len(elem)
68        if children:
69                for item in elem:
70                        result+='\n'+PrettyPrint(item,indent=indent+space)
71                result+='\n%s%s</%s>'%(indent,estrip(item.tail),elem.tag)
72        else:
73                result+='</%s>'%(elem.tag)
74        return result
75
76# fixing up namespaces:
77def removeInlineNS(csmlstring):
78        #  removeInlineNS: function removes "inline" namespaces and declares them as part of the Dataset element.
79   
80        #replace any fully qualified namespaces
81        csmlstring=csmlstring.replace('{http://www.opengis.net/gml}', 'gml:')
82        csmlstring=csmlstring.replace('{http://ndg.nerc.ac.uk/csml}','')
83        csmlstring=csmlstring.replace('{http://www.w3.org/1999/xlink}','xlink:')
84        csmlstring=csmlstring.replace('{http://www.opengis.net/om}','om:')
85        csmlstring=csmlstring.replace('{http://www.opengis.net/swe}','swe:')               
86        csmlstring=csmlstring.replace('{http://ndg.nerc.ac.uk/moles}','moles:')
87        #remove cmsl: prefixes
88        csmlstring=csmlstring.replace('<csml:','<')
89        csmlstring=csmlstring.replace('</csml:','</')
90       
91        #add namespace declarations at top of document
92        csmlstring=csmlstring.replace('<Dataset', '<Dataset xmlns="http://ndg.nerc.ac.uk/csml"  xmlns:gml="http://www.opengis.net/gml" xmlns:om="http://www.opengis.net/om" xmlns:swe="http://www.opengis.net/swe"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:moles="http://ndg.nerc.ac.uk/moles"  xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://ndg.nerc.ac.uk/csml/ csmlDataset.xsd"')
93       
94        #this is only used when creating a new csml document
95        csmlstring=csmlstring.replace('ns0', 'gml')
96        csmlstring=csmlstring.replace('xmlns:ns1', 'xmlns:xlink')
97        csmlstring=csmlstring.replace('ns1:href', 'xlink:href')
98        csmlstring=csmlstring.replace('ns1:moles', 'xlink:moles')
99        csmlstring=csmlstring.replace('ns1:', '')  #the rest of the ns1s are CSML namespaces... due to the way it has been parsed.       
100        #what about SWE - need to check this ********TODO*****
101        return csmlstring
102
103
104def isURI(uri):
105    """ a very simple function to test if a string is a uri
106    if ;// appears in the first 12 characters it is probably a uri """
107    #TODO - a decent uri check!   
108    result = False
109    if string.find(uri[:12], '://') != -1:
110        result = True
111    return result
112
113
114class ParserPostProcessor:
115    def __init__(self,dataset): 
116       
117        self.dataset=dataset
118       
119    def __findFLmatch(self, href):
120        for sd in csml.csmllibs.csmlextra.listify(self.dataset.storageDescriptor.descriptors):
121            if type(sd)==csml.parser.AggregatedArray:
122                for comp in csml.csmllibs.csmlextra.listify(sd.components):
123                    if hasattr(comp, 'fileList'):
124                        if hasattr(comp.fileList, 'id'):
125                            if comp.fileList.id==href:
126                                return comp.fileList
127       
128                       
129    def __findSDmatch(self, href):     
130        for sd in csml.csmllibs.csmlextra.listify(self.dataset.storageDescriptor.descriptors):
131            if type(sd) in [csml.parser.NetCDFExtract, csml.parser.AggregatedArray]:
132                if hasattr(sd, 'id'):
133                     if sd.id == href:
134                        return sd
135                       
136               
137       
138    def resolveReferences(self):
139        #Need to do this in more simple manner! for each xlink, call csml.csmllibs.csmlxlink.resolveXlink()
140       
141        #start with fileLists in the the storage descriptors:
142        if hasattr(self.dataset, 'storageDescriptor'):
143            if hasattr(self.dataset.storageDescriptor, 'descriptors'):
144                for sd in csml.csmllibs.csmlextra.listify(self.dataset.storageDescriptor.descriptors):
145                    if type(sd)==csml.parser.AggregatedArray:
146                        for comp in csml.csmllibs.csmlextra.listify(sd.components):
147                            if hasattr(comp, 'fileListXLINK'):
148                                if hasattr(comp.fileListXLINK, 'href'):                               
149                                    fList = self.__findFLmatch(comp.fileListXLINK.href[1:])
150                                    if fList is not None:
151                                        comp.fileList =fList
152                                        del comp.fileListXLINK
153       
154        # now handle any xlinks in the domain:
155        for feature in csml.csmllibs.csmlextra.listify(self.dataset.featureCollection.featureMembers):
156            cvg = feature.value
157            for att in ['gridSeriesDomain', 'pointDomain', 'profileSeriesDomain','sectionDomain','trajectoryDomain','blah blah']:
158                if hasattr(cvg, att):
159                    domain=getattr(cvg,att)
160                    for ordinate in listify(domain.coordTransformTable.gridOrdinates):
161                        if hasattr(ordinate.coordAxisValues,'href'):
162                            if ordinate.coordAxisValues.arcrole.split('#')[1] in ['coordinateList', 'timePositionList']:
163                                dataforClist= self.__findSDmatch(ordinate.coordAxisValues.href[1:])
164                            if dataforClist is not None:
165                                    setattr(ordinate.coordAxisValues, 'insertedExtract', dataforClist)
166                            else:
167                                if ordinate.coordAxisValues.arcrole.split('#')[1] == 'timePositionList':
168                                    sptlist=csml.csmllibs.csmlextra.getObjbyGMLID(self.dataset.elem, ordinate.coordAxisValues.href[1:])                                   
169                                    setattr(ordinate.coordAxisValues, 'timePositionList', sptlist.timePositionList)
170                                    del ordinate.coordAxisValues.href
171                                    del ordinate.coordAxisValues.show
172                                    del ordinate.coordAxisValues.role
173                                    del ordinate.coordAxisValues.arcrole
174                                    delattr (ordinate.coordAxisValues, '{http://www.w3.org/1999/xlink}href')
175                                    delattr (ordinate.coordAxisValues, '{http://www.w3.org/1999/xlink}show')
176                                    delattr (ordinate.coordAxisValues, '{http://www.w3.org/1999/xlink}role')
177                                    delattr (ordinate.coordAxisValues, '{http://www.w3.org/1999/xlink}arcrole')
178                    break
179           
180            #now the rangeSet:
181            if hasattr(feature.value.rangeSet, 'valueArray'):
182                #could be an xlink here..
183                for vc in  csml.csmllibs.csmlextra.listify(feature.value.rangeSet.valueArray.valueComponent):
184                    if hasattr(vc, 'href'):
185                        dataforQlist=self.__findSDmatch(vc.href[1:])
186                        if dataforQlist is not None:
187                            setattr(vc, 'insertedExtract', dataforQlist)
188
189        return self.dataset
190                                           
Note: See TracBrowser for help on using the repository browser.