Changeset 1694


Ignore:
Timestamp:
14/11/06 09:42:42 (13 years ago)
Author:
domlowe
Message:

XML output is now schema aware and examines the moles schema for sequence information to get the corred order of elements

Location:
TI02-CSML/trunk/csml2MolesStuff
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • TI02-CSML/trunk/csml2MolesStuff/csml2moles.py

    r1692 r1694  
    77import datetime 
    88import molesReadWrite as MRW 
     9 
     10'''call using: python csml2moles.py badc.nerc.ac.uk molesdocABC example.xml example2.xml example3.xml''' 
     11 
     12 
    913#this is a fix to the  ElementTree namespace problem that namespaces are usually represented as ns0, ns1, ns2 etc. 
    1014etree._namespace_map.update({ 
    1115        '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'}) 
    12  
    1316 
    1417def _strToDate(ymd): 
     
    207210    moles=csml.parser_extra.PrettyPrint(molestree) 
    208211    print '\n \n \n BEFORE PARSING' 
    209     #print moles 
    210     #tree.write(file='molesout.xml') 
     212    print moles 
    211213    f=open('molesout.xml','w') 
    212214    f.write(moles) 
    213215    f.close() 
    214     sys.exit() 
     216 
    215217    
    216218    #produce XML again (round trip) 
    217     tree=cElementTree.ElementTree(file='molesout.xml') 
    218     dgMeta=MRW.dgMetadata() 
    219     dgMeta.fromXML(tree.getroot()) 
    220     molestree=dgMeta.toXML() 
    221     moles=csml.parser_extra.PrettyPrint(molestree) 
    222     print '\n \n \n AFTER PARSING' 
     219    #tree=cElementTree.ElementTree(file='molesout.xml') 
     220    #dgMeta=MRW.dgMetadata() 
     221    #dgMeta.fromXML(tree.getroot()) 
     222    #molestree=dgMeta.toXML() 
     223    #moles=csml.parser_extra.PrettyPrint(molestree) 
     224    #print '\n \n \n AFTER PARSING' 
    223225    #print moles    
    224226 
  • TI02-CSML/trunk/csml2MolesStuff/molesReadWrite.py

    r1692 r1694  
    55 
    66class xmlSchema(object): 
     7    ''' this class creates a mapping of the xml schema sequences so that it can be referred to when  
     8    writing out a new moles document - this enables elements to be written in the order specified by the schema 
     9    If a particular sequence mapping can't be found then the elements will be written in whichever order python sees fit. 
     10    It tries various searches of the schema to pick out the sequences (which can be nested) 
     11    ''' 
    712    def __init__(self, schema): 
    813        self.sequences={} 
    9          
    1014        def __addSequence(molesname, sequence): 
     15            '''adds a new sequences to the list, also handles xs:choice''' 
    1116            seqlist=[] 
    1217            for elem in sequence[:]: 
     
    1520                if elem.attrib.has_key('ref'): 
    1621                    seqlist.append(elem.attrib['ref'].split(':')[1]) 
     22                if elem.tag == '{http://www.w3.org/2001/XMLSchema}choice': 
     23                    for subelem in elem[:]: 
     24                        if subelem.attrib.has_key('name'): 
     25                            seqlist.append(subelem.attrib['name']) 
    1726            self.sequences[molesname]=seqlist 
    1827 
    1928        for event, elem in ET.iterparse(schema): 
     29            '''look for sequences in complexTypes''' 
    2030            if elem.tag == '{http://www.w3.org/2001/XMLSchema}complexType': 
    2131                if elem.attrib.has_key('name'): 
     
    2737                            __addSequence(molesclassname,subelem) 
    2838            if elem.tag == '{http://www.w3.org/2001/XMLSchema}element': 
    29                     #complexType is declared but does not have a name. 
    30                     #the name must belong to the parent 'element' element. 
     39                '''Look for parents of complex types - sometimes a complexType is declared but does not have a name and 
     40              the name belongs to the parent 'element' element.''' 
    3141                if elem.attrib.has_key('name'): 
    3242                    molesclassname= elem.attrib['name'] 
     
    3646                                if subsubelem.tag=='{http://www.w3.org/2001/XMLSchema}sequence': 
    3747                                    __addSequence(molesclassname,subsubelem) 
    38  
    39     def lookupOrder(self, classname): 
     48            '''this bit handles the use of types. If some element has a name and a type attribute then if that type is complex it has 
     49            the same sequence as the type e.g. <xs:element name="dataModelID" type="moles:dgMetadataIDType"> 
     50            need to run iterparse again as this needs to be done when all elements have already been parsed. ''' 
     51            for event, elem in ET.iterparse(schema): 
     52                if elem.tag == '{http://www.w3.org/2001/XMLSchema}element': 
     53                    if elem.attrib.has_key('name'): 
     54                        molesclassname= elem.attrib['name'] 
     55                        if elem.attrib.has_key('type'): 
     56                            typename=elem.attrib['type'] 
     57                            if typename[-4:]=='Type': 
     58                                 typename=typename[:-4].split(':')[1]  #may also be prefixed by moles 
     59                            try: 
     60                                seq=self.sequences[typename] 
     61                                self.sequences[molesclassname]=seq 
     62                            except KeyError: 
     63                                pass  #can't find anything 
     64         
     65             
     66    def lookupOrder(self, dict,classname): 
     67        '''takes the attributes in a dictionary and orders them according to the schema sequence''' 
    4068        try: 
    4169            order=self.sequences[classname] 
    4270        except KeyError: 
    43             order = None 
     71            order = [] 
     72            for key in dict: 
     73                order.append(dict[key]) # if it can't be found an unordered list is returned from the original dictionary items 
    4474        return order 
    4575 
    4676class molesElement(object): 
     77    ''' molesElement class - base class of all elements ''' 
    4778    def __init__(self, namespace=None, **kwargs): 
    4879        if namespace !=None: 
     
    5182            self.ns = 'http://ndg.nerc.ac.uk/moles' 
    5283        self.__dict__.update(kwargs) 
    53          
    54     def _combineattributes(self,attname, newChild): 
     84     
     85    def __combineattributes(self,attname, newChild): 
    5586        att = getattr(self,attname) 
    5687        if isinstance(att,molesElement): 
     
    5990            att.append(newChild) 
    6091            setattr(self, attname,att) 
    61              
     92         
    6293    def toXML(self,molesFrag, schema=None): 
    6394        if schema != None: 
     
    6596        else: 
    6697            self.schema=None 
    67         for attr in self.__dict__: 
    68             order=schema.lookupOrder(attr) 
    69             print order 
    70             if attr=='ns': 
    71                 pass 
    72             if attr=='schema': 
    73                 pass 
    74             elif isinstance(self.__dict__[attr], molesElement): 
    75                 frag=ET.Element(attr) 
    76                 self.__dict__[attr].toXML(frag,schema=self.schema) 
    77                 molesFrag.append(frag) 
    78             elif isinstance(self.__dict__[attr], list): 
    79                 for item in self.__dict__[attr]: 
    80                     if isinstance(item, molesElement): 
    81                         frag=ET.Element(attr) 
    82                         item.toXML(frag, schema=self.schema) 
    83                         molesFrag.append(frag) 
    84                     else: 
    85                         frag=ET.Element(attr) 
    86                         frag.text=item 
    87             else: 
    88                 frag=ET.Element(attr) 
    89                 frag.text=self.__dict__[attr] 
    90                 molesFrag.append(frag) 
     98        orderedAttribs=schema.lookupOrder(self.__dict__,molesFrag.tag) 
     99        for item in orderedAttribs: 
     100            if hasattr(self, item): 
     101                if isinstance(self.__dict__[item], molesElement): 
     102                    frag=ET.Element(item) 
     103                    self.__dict__[item].toXML(frag,schema=self.schema) 
     104                    molesFrag.append(frag) 
     105                elif isinstance(self.__dict__[item], list): 
     106                    for it in self.__dict__[item]: 
     107                        if isinstance(it, molesElement): 
     108                            frag=ET.Element(item) 
     109                            it.toXML(frag, schema=self.schema) 
     110                            molesFrag.append(frag) 
     111                        else: 
     112                            frag=ET.Element(item) 
     113                            frag.text=it 
     114                else: 
     115                    frag=ET.Element(item) 
     116                    frag.text=self.__dict__[item] 
     117                    molesFrag.append(frag) 
    91118        return molesFrag 
    92119             
     
    103130                    kw=child.tag 
    104131                    if hasattr(self, child.tag): 
    105                         self._combineattributes(child.tag, newChild) 
     132                        self.__combineattributes(child.tag, newChild) 
    106133                    else: 
    107134                        setattr(self,child.tag, newChild) 
     
    131158    def _createClasses(self): 
    132159        #if you want more classes just add their names to this list 
     160        #could probably examine the schema here.... 
    133161        classList= \ 
    134162        ['dataModelID', \ 
Note: See TracChangeset for help on using the changeset viewer.