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

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

namespace support working better #2

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/gml': 'gml','http://ndg.nerc.ac.uk/csml' : 'csml', 'http://www.w3.org/1999/xlink':'xlink'})
9
10
11nsCSML = 'http://ndg.nerc.ac.uk/csml'
12nsGML = 'http://www.opengis.net/gml'
13nsOM = 'http://www.opengis.net/om'
14nsXLINK = 'http://www.w3.org/1999/xlink'
15nsXML = 'http://ndg.nerc.ac.uk/csml'
16nsMOLES='http://ndg.nerc.ac.uk/moles'
17
18def myQName(uri,tag):
19    return "{"+uri+"}"+tag
20
21def CSML(tag):
22    return myQName(nsCSML,tag)
23
24def GML(tag):
25    return myQName(nsGML,tag)
26
27def Merge(dict1, dict2):
28    '''merges (adds) two dictionary objects, used in attribute 'inheritance.'''
29    dict3={}
30    for item in dict1:
31        dict3[item] =dict1[item]
32    for item in dict2:
33        dict3[item] =dict2[item]
34    return dict3
35
36
37class csElement(object):
38    ''' main csElement class - all other elements inherit from this baseclass 
39    all the from/to XML conversion is done by this class'''
40   
41    def __init__(self, **kwargs):
42        if not hasattr(self, 'ATTRIBUTES'):
43            self.ATTRIBUTES=[]
44           
45       
46    def __removeURI(self, qname):
47        try:
48            attname = qname.split('}')[1]
49        except IndexError:
50            attname = qname
51        return attname
52
53    def toXML(self, csmlfrag):
54    #process self... and convert  to XML
55        for item in self.__dict__:
56            if item in self.ATTRIBUTES:
57                csmlfrag.set(item, self.__dict__[item])
58         #but probably need to handle the case where GML attributes are set without namespace
59         #to allow for  use of classname(id = 'blah')
60        for item in self.__dict__:
61            if GML(item) in self.ATTRIBUTES:
62                csmlfrag.set(GML(item), self.__dict__[item])       
63         
64    # self.CHILDREN (recursive - calls the toXML method of children)
65        for att in self.__dict__:
66            if att not in ['ATTRIBUTES', 'CHILDREN', 'CONTENT']:
67                for child in self.CHILDREN:
68                    if child == att:
69                        #found a match.
70                        ename = self.CHILDREN[child][0] #Element Name
71                        etype = self.CHILDREN[child][1] #Element Type
72                        if type(self.__dict__[att])  is list:
73                            for item in self.__dict__[att]:
74                                frag=ET.Element(ename)
75                                if self.CONTENT is not None:
76                                    frag.text=self.CONTENT
77                                item.toXML(frag)
78                                csmlfrag.append(frag)
79                        else:
80                            frag=ET.Element(ename)
81                            if self.CONTENT is not None:
82                                    frag.text=self.CONTENT
83                            self.__dict__[att].toXML(frag)
84                            csmlfrag.append(frag)
85        return csmlfrag
86       
87    def fromXML(self,csmlfrag):
88        # deal with attributes, e.g. gml id's
89        for item in csmlfrag.items():
90            if item[0] in self.ATTRIBUTES:
91                setattr(self, item[0], item[1])
92        # self.CHILDREN (recursive - calls the fromXML method of children
93        for frag in csmlfrag[:]: 
94            if frag.text is not None:
95                self.CONTENT = frag.text
96            for child in self.CHILDREN:
97                ename = self.CHILDREN[child][0] #Element Name
98                if frag.tag == ename:
99                    etype = self.CHILDREN[child][1]
100                    #Element Type                    #elem = ET.Element(ename)
101                    childobj=eval(etype)()
102                    childobj.fromXML(frag)
103                    if hasattr(self, child):
104                        if type(self.__dict__[child]) is not list:
105                            tmp=self.__dict__[child]
106                            setattr(self, child, [tmp]) #convert to list
107                        self.__dict__[child].append(childobj)
108                    else:
109                        setattr(self, child, childobj)
110
111class csString(csElement):
112    pass
113
114class AbstractGML(csElement):
115   
116    def __init__(self, **kwargs):
117        self.ATTRIBUTES=[GML('id'), GML('description')] # etc
118    #ATTRIBUTES not implemented yet.
119   
120
121class AbstractFileExtract(AbstractGML, csElement):
122    def __init__(self,**kwargs):
123        AbstractGML.__init__(self,**kwargs)
124        self.CHILDREN = {'fileName':[CSML('fileName'), 'csString']}
125
126class NetCDFExtract(AbstractFileExtract, csElement):
127    def __init__(self,**kwargs):
128        AbstractFileExtract.__init__(self, **kwargs)
129        self.CHILDREN = Merge(self.CHILDREN,{'variableName':[CSML('variableName'), 'csString']})
130        #use Merge() when inheriting CHILDREN attribute to extend rather than replace
131
132
133class Dataset(AbstractGML, csElement):   
134    ''' Dataset class, needed as root of tree'''
135    def __init__(self, **kwargs):
136        AbstractGML.__init__(self,**kwargs)
137        self.CHILDREN = {'ncExtract':[CSML('NetCDFExtract'), 'NetCDFExtract']}
138    def toXML(self):
139        csmlfrag=ET.Element(CSML('Dataset'))
140        csElement.toXML(self, csmlfrag)
141        return csmlfrag
142
143def main():
144    '''round trip for testing purposes:'''
145    tree=ET.ElementTree(file='test.xml')
146    ds=Dataset()
147    ds.fromXML(tree.getroot())
148    csmltree=ds.toXML()
149    #print csmltree
150    csmlout=csml.parser_extra.PrettyPrint(csmltree)
151    csmlout=csml.parser_extra.removeInlineNS(csmlout)
152    print csmlout
153    #print dir(csmlout)
154
155    #test writing a document from scratch:
156   
157
158if __name__=='__main__':
159    main()
Note: See TracBrowser for help on using the repository browser.