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

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

Adding backslash to schemaLocation - to allow CSML files output from
csml.parser_extra to be added to an eXist DB (NB, without this a SaxParseException? is thrown).

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