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

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

implemented some sort of substitution for AbstractFeature?

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        for item in self.__dict__:
66            if item in self.ATTRIBUTES:
67                csmlfrag.set(item, self.__dict__[item])
68         #but probably need to handle the case where GML attributes are set without namespace
69         #to allow for  use of classname(id = 'blah')
70        for item in self.__dict__:
71            if GML(item) in self.ATTRIBUTES:
72                csmlfrag.set(GML(item), self.__dict__[item])       
73         
74    # self.CHILDREN (recursive - calls the toXML method of children
75        for att in self.__dict__:
76            if att not in ['ATTRIBUTES', 'CHILDREN', 'CONTENT']:
77                for child in self.CHILDREN:
78                    if child == att:                       
79                        #found a match.
80                        if type(self.CHILDREN[child][0]) is list:
81                            ename = self._getReverseSubsType(type(self.__dict__[att]).__name__)
82                        else: 
83                            ename=self.CHILDREN[child][0]#Element Name
84                        etype = self.CHILDREN[child][1] #Element Type
85                        if type(self.__dict__[att])  is list:
86                            for item in self.__dict__[att]:
87                                frag=ET.Element(ename)
88                                if self.CONTENT is not None:
89                                    frag.text=self.CONTENT
90                                item.toXML(frag)
91                                csmlfrag.append(frag)
92                        else:
93                            frag=ET.Element(ename)
94                            if self.CONTENT is not None:
95                                    frag.text=self.CONTENT
96                            self.__dict__[att].toXML(frag)
97                            csmlfrag.append(frag)
98        return csmlfrag
99       
100    def fromXML(self,csmlfrag):
101        # deal with attributes, e.g. gml id's
102        for item in csmlfrag.items():
103            if item[0] in self.ATTRIBUTES:
104                setattr(self, item[0], item[1])
105        # self.CHILDREN (recursive - calls the fromXML method of children
106        for frag in csmlfrag[:]:
107            if frag.text is not None:
108                self.CONTENT = frag.text
109            for child in self.CHILDREN:
110                ename = self.CHILDREN[child][0] #Element Name                   
111                if frag.tag == ename:
112                    etype = self.CHILDREN[child][1]
113                    #Element Type                    #elem = ET.Element(ename)
114                    childobj=eval(etype)()
115                    childobj.fromXML(frag)
116                    if hasattr(self, child):
117                        if type(self.__dict__[child]) is not list:
118                            tmp=self.__dict__[child]
119                            setattr(self, child, [tmp]) #convert to list
120                        self.__dict__[child].append(childobj)
121                    else:
122                        setattr(self, child, childobj)
123                if type(ename) is list: # e.g. FeatureCollection where it can be GridFeature, PointFeature etc..
124                    if frag.tag in ename:
125                        etype=self._getSubstitutionType(frag.tag)
126                        childobj=eval(etype)()
127                    childobj.fromXML(frag)
128                    if hasattr(self, child):
129                        if type(self.__dict__[child]) is not list:
130                            tmp=self.__dict__[child]
131                            setattr(self, child, [tmp]) #convert to list
132                        self.__dict__[child].append(childobj)
133                    else:
134                        setattr(self, child, childobj)
135               
136class csString(csElement):
137    pass
138
139class AbstractGML(csElement):
140    def __init__(self, **kwargs):
141        self.ATTRIBUTES=[GML('id'), GML('description'), GML('name'), 'MetaDataProperty']
142
143class AbstractFeature(AbstractGML,csElement):
144    def __init__(self, **kwargs):
145        AbstractGML.__init__(self,**kwargs)
146        self.CHILDREN={'boundedBy':[GML('boundedBy'), 'Envelope']}
147
148class AbstractFeatureCollection(AbstractFeature,csElement):
149    def __init__(self, **kwargs):
150        AbstractFeature.__init__(self,**kwargs)
151        self.CHILDREN=merge(self.CHILDREN,{'members':[[CSML('GridFeature'),CSML('PointFeature')], 'AbstractFeature']})
152        #CHOICE mechanism  used to declare that any element name can go here so long as it is of a type that
153        #inherits from AbstractFeature - .i.e. a GridFeature, a PointFeature etc.
154       
155class GridFeature(AbstractFeature, csElement):
156    def __init__(self, **kwargs):
157        AbstractFeature.__init__(self,**kwargs)
158        #dummy child for now:
159        self.CHILDREN=merge(self.CHILDREN,{'test':[CSML('TestElement'), 'csString']})
160        #self.CHILDREN={'time':[GML('time'), GML('TimePosition')], 'value':[CSML('value'), 'ReferenceableGridCoverage'], 'parameter':[CSML('parameter'), SWE('Phenomenon')]}
161
162class AbstractFileExtract(AbstractGML, csElement):
163    def __init__(self,**kwargs):
164        AbstractGML.__init__(self,**kwargs)
165        self.CHILDREN = {'fileName':[CSML('fileName'), 'csString']}
166
167class NetCDFExtract(AbstractFileExtract, csElement):
168    def __init__(self,**kwargs):
169        AbstractFileExtract.__init__(self, **kwargs)
170        self.CHILDREN = merge(self.CHILDREN,{'variableName':[CSML('variableName'), 'csString']})
171        #use Merge() when inheriting CHILDREN attribute to extend rather than replace
172
173class FeatureCollection(AbstractFeatureCollection,csElement):
174    def __init__(self,**kwargs):
175        AbstractFeatureCollection.__init__(self,**kwargs)
176   
177    def _getSubstitutionType(self,tag):
178        if tag==CSML('GridFeature'):
179            return 'GridFeature'
180        elif tag==CSML('PointFeature'):
181            return 'PointFeature'
182        else: return 'AbstractFeature'
183   
184    def _getReverseSubsType(self, typename):
185        if typename== 'GridFeature':
186            return CSML('GridFeature')
187        elif typename == 'PointFeature':
188            return CSML('PointFeature')
189        else: return CSML('AbstractFeature')
190           
191           
192       
193class Dataset(AbstractGML, csElement):   
194    ''' Dataset class, needed as root of tree'''
195    def __init__(self, **kwargs):
196        AbstractGML.__init__(self,**kwargs)
197        self.CHILDREN = {'ncExtract':[CSML('NetCDFExtract'), 'NetCDFExtract'], 'featureCollection':[CSML('featureCollection'),'FeatureCollection']}
198    def toXML(self):
199        csmlfrag=ET.Element(CSML('Dataset'))
200        csElement.toXML(self, csmlfrag)
201        return csmlfrag
202
203def main():
204    '''round trip for testing purposes:'''
205    print '\n'
206    tree=ET.ElementTree(file='test.xml')
207    ds=Dataset()
208    ds.fromXML(tree.getroot())
209    csmltree=ds.toXML()
210    #print csmltree
211    csmlout=csml.parser_extra.PrettyPrint(csmltree)
212    csmlout=csml.parser_extra.removeInlineNS(csmlout)
213    print '\n %s'% csmlout
214    #print dir(csmlout)
215
216    #test writing a document from scratch:
217   
218
219if __name__=='__main__':
220    main()
Note: See TracBrowser for help on using the repository browser.