source: TI02-CSML/branches/CSML2/csParser.py @ 1742

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/branches/CSML2/csParser.py@1742
Revision 1742, 9.4 KB checked in by domlowe, 13 years ago (diff)

collections of features working

Line 
1import cElementTree as ET
2import elementtree.ElementTree as etree
3import csml.parser_extra
4
5'''CSML v2 Parser ''' 
6
7#this map needs updating for V2
8etree._namespace_map.update({'http://www.opengis.net/om': 'om', 'http://www.opengis.net/swe': 'swe',  'http://www.opengis.net/gml': 'gml','http://ndg.nerc.ac.uk/csml' : 'csml', 'http://www.w3.org/1999/xlink':'xlink'})
9
10       
11
12nsCSML = 'http://ndg.nerc.ac.uk/csml'
13nsGML = 'http://www.opengis.net/gml'
14nsOM = 'http://www.opengis.net/om'
15nsXLINK = 'http://www.w3.org/1999/xlink'
16nsXML = 'http://ndg.nerc.ac.uk/csml'
17nsMOLES='http://ndg.nerc.ac.uk/moles'
18nsSWE='http://www.opengis.net/swe'
19   
20def myQName(uri,tag):
21    return "{"+uri+"}"+tag
22
23def CSML(tag):
24    return myQName(nsCSML,tag)
25
26def GML(tag):
27    return myQName(nsGML,tag)
28
29def SWE(tag):
30    return myQName(nsSWE,tag)
31
32def merge(dict1, dict2):
33    '''merges (adds) two dictionary objects, used in attribute 'inheritance.'''
34    dict3={}
35    for item in dict1:
36        dict3[item] =dict1[item]
37    for item in dict2:
38        dict3[item] =dict2[item]
39    return dict3
40
41class csElement(object):
42    ''' main csElement class - all other elements inherit from this baseclass 
43    all the from/to XML conversion is done by this class'''
44   
45    def __init__(self, **kwargs):
46        if not hasattr(self, 'ATTRIBUTES'):
47            self.ATTRIBUTES=[]
48           
49       
50    def __removeURI(self, qname):
51        try:
52            attname = qname.split('}')[1]
53        except IndexError:
54            attname = qname
55        return attname
56       
57    def _getSubstitutionType(self,tag):
58        pass #stub
59   
60    def _getReverseSubsType(self, typename):
61        pass #stub
62   
63    def toXML(self, csmlfrag):
64    #process self... and convert  to XML
65        if hasattr(self, 'CONTENT'):
66                if self.CONTENT is not None: csmlfrag.text=self.CONTENT
67        for item in self.__dict__:
68            if item in self.ATTRIBUTES:
69                csmlfrag.set(item, self.__dict__[item])
70         #but probably need to handle the case where GML attributes are set without namespace
71         #to allow for  use of classname(id = 'blah')
72        for item in self.__dict__:
73            if GML(item) in self.ATTRIBUTES:
74                csmlfrag.set(GML(item), self.__dict__[item])       
75    # self.CHILDREN (recursive - calls the toXML method of children
76        for att in self.__dict__:
77            if att not in ['ATTRIBUTES', 'CHILDREN', 'CONTENT']:
78                for child in self.CHILDREN:
79                    if child == att:                       
80                        #found a match.
81                        if type(self.CHILDREN[child][0]) is not list:
82                            ename=self.CHILDREN[child][0]#Element Name
83                        etype = self.CHILDREN[child][1] #Element Type
84                        if type(self.__dict__[att])  is list:
85                            for item in self.__dict__[att]:
86                                ename = self._getReverseSubsType(type(item).__name__)
87                                frag=ET.Element(ename)
88                                item.toXML(frag)
89                                csmlfrag.append(frag)
90                        else:
91                            frag=ET.Element(ename)
92                            self.__dict__[att].toXML(frag)
93                            csmlfrag.append(frag)
94           
95        return csmlfrag
96       
97    def fromXML(self,csmlfrag):
98        ######## output for testing purposes ###############
99        if hasattr(self, 'CHILDREN'):
100            print "ELEMENT %s"%csmlfrag.tag
101            for child in self.CHILDREN:
102                print child       
103         #######################################
104        # deal with attributes, e.g. gml id's
105        if csmlfrag.text is not None:
106                self.CONTENT = csmlfrag.text
107        for item in csmlfrag.items():
108            if item[0] in self.ATTRIBUTES:
109                setattr(self, item[0], item[1])
110        # self.CHILDREN (recursive - calls the fromXML method of children
111        for frag in csmlfrag[:]:
112            print "ELEMENT %s"%csmlfrag.tag
113            for child in self.CHILDREN:
114                print child
115                ename = self.CHILDREN[child][0] #Element Name                   
116                if frag.tag == ename:
117                    etype = self.CHILDREN[child][1]
118                    #Element Type                    #elem = ET.Element(ename)
119                    childobj=eval(etype)()
120                    childobj.fromXML(frag)
121                    if hasattr(self, child):
122                        if type(self.__dict__[child]) is not list:
123                            tmp=self.__dict__[child]
124                            setattr(self, child, [tmp]) #convert to list
125                        self.__dict__[child].append(childobj)
126                    else:
127                        setattr(self, child, childobj)
128                if type(ename) is list: # e.g. FeatureCollection where it can be GridFeature, PointFeature etc..
129                    if frag.tag in ename:
130                        etype=self._getSubstitutionType(frag.tag)
131                        childobj=eval(etype)()
132                    childobj.fromXML(frag)
133                    if hasattr(self, child):
134                        if type(self.__dict__[child]) is not list:
135                            tmp=self.__dict__[child]
136                            setattr(self, child, [tmp]) #convert to list
137                        self.__dict__[child].append(childobj)
138                    else:
139                        setattr(self, child, childobj)
140               
141class csString(csElement):
142    pass
143
144class AbstractGML(csElement):
145    def __init__(self, **kwargs):
146        self.ATTRIBUTES=[GML('id'), GML('description'), GML('name'), 'MetaDataProperty']
147
148class AbstractFeature(AbstractGML,csElement):
149    def __init__(self, **kwargs):
150        AbstractGML.__init__(self,**kwargs)
151        self.CHILDREN={'boundedBy':[GML('boundedBy'), 'Envelope']}
152
153class AbstractFeatureCollection(AbstractFeature,csElement):
154    def __init__(self, **kwargs):
155        AbstractFeature.__init__(self,**kwargs)
156        self.CHILDREN=merge(self.CHILDREN,{'members':[[CSML('GridFeature'),CSML('PointFeature')], 'AbstractFeature']})
157
158#class TimePosition(AbstractGML):
159    #def __init__(self, **kwargs):
160        #AbstractGML.__init__(self,**kwargs)
161        #self.CHILDREN = {'':[CSML(''), '']}   
162
163class TimePosition(AbstractGML):
164    def __init__(self, **kwargs):
165        AbstractGML.__init__(self,**kwargs)
166        self.CHILDREN = {'':[CSML(''), '']}   
167       
168class ReferenceableGridCoverage(AbstractGML):
169    def __init__(self, **kwargs):
170        AbstractGML.__init__(self,**kwargs)
171        self.CHILDREN = {'':[CSML(''), '']}   
172
173class Phenomenon(AbstractGML):
174    def __init__(self, **kwargs):
175        AbstractGML.__init__(self,**kwargs)
176        self.CHILDREN = {'':[CSML(''), '']}   
177       
178class GridFeature(AbstractFeature, csElement):
179    def __init__(self, **kwargs):
180        AbstractFeature.__init__(self,**kwargs)
181        #dummy child for now:
182        #self.CHILDREN=merge(self.CHILDREN,{'test':[CSML('TestElement'), 'csString']})
183        self.CHILDREN={'time':[GML('time'), GML('TimePosition')], 'value':[CSML('value'), 'ReferenceableGridCoverage'], 'parameter':[CSML('parameter'), 'Phenomenon']} 
184
185class AbstractFileExtract(AbstractGML, csElement):
186    def __init__(self,**kwargs):
187        AbstractGML.__init__(self,**kwargs)
188        self.CHILDREN = {'fileName':[CSML('fileName'), 'csString']}
189
190class NetCDFExtract(AbstractFileExtract, csElement):
191    def __init__(self,**kwargs):
192        AbstractFileExtract.__init__(self, **kwargs)
193        self.CHILDREN = merge(self.CHILDREN,{'variableName':[CSML('variableName'), 'csString']})
194        #use Merge() when inheriting CHILDREN attribute to extend rather than replace
195
196class FeatureCollection(AbstractFeatureCollection,csElement):
197    def __init__(self,**kwargs):
198        AbstractFeatureCollection.__init__(self,**kwargs)
199   
200   
201    def _getSubstitutionType(self,tag):
202        print tag
203        print 'returning..'
204        if tag==CSML('GridFeature'):
205            print 'GF'
206            return 'GridFeature'
207        elif tag==CSML('PointFeature'):
208            print 'PF'
209            return 'PointFeature'
210        else: 
211            print 'AF'
212            return 'AbstractFeature'
213   
214    def _getReverseSubsType(self, typename):
215        print 'REVERSE'
216        print typename
217        if typename== 'GridFeature':
218            return CSML('GridFeature')
219        elif typename == 'PointFeature':
220            return CSML('PointFeature')
221        else: return CSML('AbstractFeature')
222           
223           
224       
225class Dataset(AbstractGML, csElement):   
226    ''' Dataset class, needed as root of tree'''
227    def __init__(self, **kwargs):
228        AbstractGML.__init__(self,**kwargs)
229        self.CHILDREN = {'ncExtract':[CSML('NetCDFExtract'), 'NetCDFExtract'], 'featureCollection':[CSML('featureCollection'),'FeatureCollection']}
230    def toXML(self):
231        csmlfrag=ET.Element(CSML('Dataset'))
232        csElement.toXML(self, csmlfrag)
233        return csmlfrag
234
235def main():
236    '''round trip for testing purposes:'''
237    print '\n'
238    tree=ET.ElementTree(file='test.xml')
239    ds=Dataset()
240    ds.fromXML(tree.getroot())
241    csmltree=ds.toXML()
242    #print csmltree
243    csmlout=csml.parser_extra.PrettyPrint(csmltree)
244    csmlout=csml.parser_extra.removeInlineNS(csmlout)
245    print '\n %s'% csmlout
246    #print dir(csmlout)
247
248    #test writing a document from scratch:
249   
250
251if __name__=='__main__':
252    main()
Note: See TracBrowser for help on using the repository browser.