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

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

schema name change

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