#!/usr/bin/python3 # -*- coding: utf-8 -*- from lxml import etree from xml.sax.expatreader import AttributesImpl import sys, urllib objectTypes = dict(); dataTypes = dict(); primitiveTypes = dict(); imports = dict(); parsedImports = dict(); nbPassOnRoot= 0; rootObjectId = None indent = 1; print("==============") class vodmlObjectType: def __init__(self, vomdlid, name, superclass, attributes): self.vodmlid = vomdlid self.name = name self.superclass = superclass self.attributes = attributes def __str__(self): retour = "OBJECT " if self.superclass != '': retour += "(extends " + self.superclass + ") " retour += self.name + " " + self.vodmlid +"\n" for attribute in self.attributes: retour += attribute.__str__() return retour def __repr__(self): return self.__str__() class vodmlDataType: def __init__(self, vodmlid, name, ref, attributes): self.vodmlid = vodmlid self.ref = ref self.name = name self.attributes = attributes def __str__(self): retour = "DATATYPE " + self.name + " " + self.vodmlid + " " + self.ref +"\n" for attribute in self.attributes: retour += attribute.__str__() return retour def __repr__(self): retour = "DATATYPE " + self.name + " " + self.vodmlid + " " + self.ref +"\n" for attribute in self.attributes: retour += attribute.__str__() return retour class vodmlAttribute: def __init__(self, vomdlid, name, datatype, arraySize): self.vodmlid = vomdlid self.name = name self.datatype = datatype self.arraySize = arraySize def __str__(self): retour = "ATTRIBUTE " retour += "(arraySize " + str(self.arraySize) + ") " retour += self.name + " " + self.vodmlid +"\n" retour += self.datatype.__str__() return retour def __repr__(self): return self.__str__() class vodmlImport: def __init__(self, name, url): self.name = name self.url = url def __str__(self): retour = "IMPORT " + self.name + " " + self.url +"\n" return retour def __repr__(self): retour = "IMPORT " + self.name + " " + self.url +"\n" return retour def readPackage(modelName, packageNode): if packageNode.tag == 'package': packageName = packageNode.find("name").text print (">>>>>>>>>> PACKAGE " + packageName) for child in packageNode.findall('*'): if child.tag == "objectType": ot = readObjectType(modelName, child) logMsg("ADD OBJECT " , ot.vodmlid) objectTypes[ot.vodmlid] = ot elif child.tag == 'primitiveType' or child.tag == 'enumeration': dt = readDataType(modelName, child) logMsg("ADD TYPE " , dt.vodmlid) primitiveTypes[dt.vodmlid] = dt elif child.tag == "dataType" : ot = readDataType(modelName, child) logMsg("ADD DATA " , ot.vodmlid) dataTypes[ot.vodmlid] = ot elif child.tag == 'package': readPackage(modelName, child) def readDataType(modelName,datatypeTag): vodmlid = '' name = '' ref = '' attributes = [] for datatypeTagChild in datatypeTag.findall('*'): if datatypeTagChild.tag == "vodml-id": vodmlid = modelName + ":" + datatypeTagChild.text elif datatypeTagChild.tag == "name": name = datatypeTagChild.text elif datatypeTagChild.tag == "vodml-ref": ref = datatypeTagChild.text elif datatypeTagChild.tag == "constraint": pass # attributes.append(readConstraint(modelName,datatypeTagChild)) elif datatypeTagChild.tag == "attribute": attributes.append(readAttribute(modelName,datatypeTagChild)) elif datatypeTagChild.tag == "reference": attributes.append(readReference(modelName,datatypeTagChild)) return vodmlDataType(vodmlid, name, ref, attributes) def readAttribute(modelName,attributeTag): dataType = '' arraySize = 2 for attributeTagChild in attributeTag.findall('*'): if attributeTagChild.tag == "vodml-id": vodmlid = modelName + ":" + attributeTagChild.text elif attributeTagChild.tag == "name": name = attributeTagChild.text elif attributeTagChild.tag == "multiplicity": for multiplicityTagChild in attributeTagChild.findall('maxOccurs'): arraySize = int(multiplicityTagChild.text) elif attributeTagChild.tag == "datatype" or attributeTagChild.tag == 'reference': dataType = readDataType(modelName,attributeTagChild) return vodmlAttribute(vodmlid, name, dataType, arraySize) def readReference(modelName,ReferenceTag): for ReferenceTagChild in ReferenceTag.findall('*'): if ReferenceTagChild.tag == "vodml-id": vodmlid = modelName + ":" + ReferenceTagChild.text elif ReferenceTagChild.tag == "name": name = ReferenceTagChild.text elif ReferenceTagChild.tag == "datatype": dataType = readDataType(modelName,ReferenceTagChild) return vodmlAttribute(vodmlid, name, dataType, 1) def readObjectType(modelName, objectTypeTag): attributes = [] superclass = '' for objectTypeChild in objectTypeTag.findall('*'): if objectTypeChild.tag == "vodml-id": vodmlid = modelName + ":" + objectTypeChild.text elif objectTypeChild.tag == "name": name = objectTypeChild.text elif objectTypeChild.tag == "composition": for multiplicityTagChild in objectTypeChild.findall('maxOccurs'): arraySize = int(multiplicityTagChild.text) att = readAttribute(modelName,objectTypeChild) attributes.append(att) elif objectTypeChild.tag == "extends": for superTypeChild in objectTypeChild.findall('vodml-ref'): superclass = superTypeChild.text break elif objectTypeChild.tag == "attribute": attributes.append(readAttribute(modelName,objectTypeChild)) elif objectTypeChild.tag == "reference": attributes.append(readReference(modelName,objectTypeChild)) obj = vodmlObjectType(vodmlid, name, superclass, attributes) return obj ''' if vodmlid.endswith('PolarizationSpace'): print( obj) print( "EXIT") sys.exit() ''' def parseVodmlFile(filename='', model=None): print( "Reading FILE " + filename + " for model ", model) if filename.startswith("http://") or filename.startswith("https://") : tree = etree.ElementTree(file=urllib.request.urlopen(filename)) else : tree = etree.parse(filename) root = tree.getroot() ns = {"vo-dml": "http://www.ivoa.net/xml/VODML/v1"} if model == None: modelName = root.find("name").text else : modelName = model print( "PARSE FILE " + filename + " for model ", model) for node in tree.xpath("import"): name = node.find('name').text url = node.find('url').text if not name in imports: # Let's take the import name as VODML prefix modelName = name print ("PARSE IMPORT " + name) parseVodmlFile(filename=url, model=modelName) print ("END PARSE " + name) imports[name]=url if model == None: modelName = root.find("name").text else : modelName = model print (model , " " , modelName) for node in tree.xpath("*"): if node.tag == 'package': readPackage(modelName, node) elif node.tag == 'primitiveType' or node.tag == 'enumeration': dt = readDataType(modelName, node) logMsg("ADD TYPE " , dt.vodmlid) primitiveTypes[dt.vodmlid] = dt elif node.tag == 'dataType' or node.tag == 'reference': dt = readDataType(modelName, node) logMsg("ADD DATA " , dt.vodmlid) dataTypes[dt.vodmlid] = dt elif node.tag == 'objectType': dt = readObjectType(modelName, node) logMsg("ADD OBJECT " , dt.vodmlid) objectTypes[dt.vodmlid] = dt def generateSingleAttributeMapping(attribute): ref = attribute.datatype.ref if ref in primitiveTypes: appendOuput( "") appendOuput( "") elif ref in dataTypes : dt = dataTypes[ref] generateDataMapping(dt, attribute.vodmlid, attribute.arraySize) elif ref in objectTypes : generateObjectMapping(objectTypes[ref], attribute.vodmlid, attribute.arraySize) else: print("REF NOT FOUND " + ref) print ("PRIM ", primitiveTypes.keys()) print ("TYPE ", dataTypes.keys()) print ("OBJ ",objectTypes.keys()) sys.exit() def generateAttributeMapping(attribute): if attribute.arraySize == 0 : return elif attribute.arraySize == 1: generateSingleAttributeMapping(attribute) elif attribute.arraySize == -1: appendOuput( "") generateSingleAttributeMapping(attribute) appendOuput( "") else: appendOuput( "") for num in range(0, attribute.arraySize): generateSingleAttributeMapping(attribute) appendOuput( "") def generateDataMapping(objectType, attrId, arraySize): appendOuput( "") for attribute in objectType.attributes: generateAttributeMapping(attribute) appendOuput( "") def generateObjectMapping(objectType, attrId, arraySize): appendOuput( "") readAttributes = [] for attribute in objectType.attributes: if attribute.vodmlid not in readAttributes: generateAttributeMapping(attribute) readAttributes.append(attribute.vodmlid) else: print( "SKIPPP " + attribute.vodmlid ) appendOuput( "") def appendOuput(string): space = " " global indent blank = '' if string.startswith(" 10: sys.exit() def logMsg(label, msg): #if( msg.endswith("SpatialCoord")): print(label + " " + msg) def resolveInheritance(): for obj in objectTypes.values(): if obj.superclass != '': if obj.superclass in objectTypes : sc = objectTypes[obj.superclass] obj.attributes = sc.attributes + obj.attributes elif obj.superclass in dataTypes: sc = objectTypes[obj.superclass] obj.attributes = sc.attributes + obj.attributes else: print( obj.vodmlid + ": Neither dataType or objectType with key " + obj.superclass + " found") sys.exit(1) def generateMapping(): print(rootObjectId) rootObjectType = objectTypes[rootObjectId] generateObjectMapping(rootObjectType, 'root', 1) def main(): global rootObjectId parseVodmlFile(filename="../models/timeseries.vo-dml.xml", model='timeseries') resolveInheritance(); rootObjectId = 'timeseries:TimeSerie' generateMapping() #parseVodmlFile(filename="/home/michel/workspace/vo-datamodels/provenance/vo-dml/xml/ProvenanceDM.vo-dml.xml", model='provenance') #rootObjectId = 'provenance:provenance.Entity' #print(rootObjectId) #generateMapping() if __name__ == "__main__": main()