xml2nod3.py 5.47 KB
#!/usr/bin/env python

import sys

if sys.path[0] == "": sys.path.pop(0)
SourceDir = sys.path[0]+"/"

class XmlStructure:
    def __init__(self, filename="NOD3.xml"):
        self.create(filename)
        
    def create(self, filename):
        from xml.dom.minidom import parse, parseString

        # parse XML file by name
        dom = parse(SourceDir + filename)

        # normalize whitespaces
        dom.documentElement.normalize()

        # first element is the Scan
        XmlScan=dom.documentElement
        
        # scan consists of image- and process-definitions
        # print "Reading XML: "+XmlScan.nodeName
        self.XmlScan=SubStructure(XmlScan)

class SubStructure:

    """ Analyze XML SubStructure """

    def __init__(self, process):
        self.create(process)
    
    def create(self, process):
        # analyze element (elements can have elements(nodeType 1),
	# attributes (nodeType 2), text (nodeType 3)
        if process.hasChildNodes():
            self.images={}
            for element in process.childNodes:
                
                # create images if one found in process definition
                if element.nodeType == 1 and element.getAttribute('content') == 'image':
                    self.images[str(element.tagName)]=element
                    # print "..... Table "+element.nodeName+" found in XML."

                # analyse substructure (process-definition) if one is found
                elif element.nodeType == 1 and element.getAttribute('content') == 'process':
                    struc=SubStructure(element)
                    for key in struc.images.keys():
                        self.images[key]=struc.images[key]

class NOD3_Fits:

    def __init__(self, XmlFile="NOD3.xml"):

        self.XmlObject = XmlStructure(XmlFile)
        self.KeyList = []
        self.XmlFile = XmlFile
        self.create()
        #del self.XmlObject
        #del self.KeyList
        #del self.XmlFile

    def create(self):

        Images = self.XmlObject.XmlScan.images.keys()
        for image in Images:
            name = self.XmlObject.XmlScan.images[image]
            self.getXMLHeaderKeywords(name)

    
    def getXMLHeaderKeywords(self, Image):
        """ creates keywords from a XML image's header keywords  """

        Header = Image.getElementsByTagName('HEADER')[0]
        HeaderKeywds = Header.childNodes
        for Keyword in HeaderKeywds:
            if Keyword.nodeType == 1:
               self.createEntityAtribute(Keyword)

    def createEntityAtribute(self, XmlElement, ImageName=None):
        """ creates attributes from either a header or a binary image
        and sets them to the Python None object """

        comment = XmlElement.attributes.items()
        if XmlElement.hasChildNodes() == 1:
           # search for the value of the tag (nodeType=3:Text) containing
           # its keyword-name. Somewhat ugly, but I didn't find a method
           # for direct access to the enclosed text
           for XmlNode in XmlElement.childNodes:
               if XmlNode.nodeType == 3:
                  name = str(XmlNode.data)
        else:
           raise ValueError, "Keyword not defined"
        # Takes "-" out of the name, if given 
        if '-' in name:
           names = string.split(name,'-')
           name = string.join(names,'_')

        # Add the ImageName to the attribute's name
        if ImageName == None:
           setattr(self, name, comment)
        else:
           name = string.join(string.split(ImageName,'-'),'_')+'_'+name
           setattr(self, name, comment)
        self.KeyList.append(str(name))

    def NOD3Header(self):

        """ get all nod3 header information defined by the xml file """

        out = {}
        for key in self.KeyList:
            out[key] = self.getHeaderInfo(key)
            #print key, self.getHeaderInfo(key)
        return self.KeyList, out

    def getHeaderInfo(self, key):

        """ get comment, form and unit from the header
            returns tuple (form, comment, unit)"""

        keys = vars(self)
        keydef = dict(keys[key])
        if 'value' in keydef: value = keydef['value']
        else: value = ""
        comment = str(keydef['description'])
        if 'unit' in keydef:
           unit = keydef['unit']
           comment = comment + " [" + unit + "]"
        else: unit = ' '
        form = keydef['type']

        return form, value, comment, unit


    def __str__(self):
        """ This method is called by the 'print' instruction. It
        defines an output format to display informations on the
        content (attributes) of an ObsEntity object. """
        # Get the list of attributes of the object
        attrDic = vars(self)            # returns a dictionnary
        attrNames = attrDic.keys()      # names of the attributes
        attrNames.sort()

        out = ''
        for attr in attrNames:
            value = attrDic[attr]
            if (type(value) == list):
                typ = str("list of %16s" % (type(value[0])))
                nbVal = str("%3i elements" % (len(value)))
            #elif (type(value) == type(array([]))):
            #    val1D = ravel(value)
            #    typ = str("array of %15s" % (type(val1D[0])))
            #    nbVal = str(shape(value))
            else:
                typ = str("%s" % (type(value)))
                nbVal = str(" = %s" % (value))

            out = out+str("%20s %24s %20s\n" % (attr,typ,nbVal))

        return out


def main():

    nod3 = NOD3_Fits()
    print nod3.NOD3Header()

if __name__ == '__main__':
    main()