• Login
  • Help/Guide
  • About Trac
  • Preferences
  • Wiki
  • Timeline
  • Roadmap
  • Browse Source
  • View Tickets
  • Search

Context Navigation

  • ← Previous Change
  • Next Change →

Changeset 76 for Xml/Validator

Show
Ignore:
Timestamp:
08/03/07 15:13:56 (16 months ago)
Author:
andrew
Message:

New version with with parse to dom code from Chris

Files:
1 modified

  • Xml/Validator/Backend/OmeValidator.py (modified) (14 diffs)

Legend:

Unmodified
Added
Removed
  • Xml/Validator/Backend/OmeValidator.py

    r75 r76  
    22# encoding: utf-8 
    33""" 
    4 OMETiffValidator.py 
     4OmeValidator.py 
    55 
    66Created by Andrew Patterson on 2007-07-24. 
    … …  
    1919# Standard Imports 
    2020import logging 
     21from xml.dom.minidom import getDOMImplementation 
    2122from StringIO import StringIO 
    2223from xml import sax 
     24import os 
     25from stat import * 
    2326 
    2427# Try to load Image for XML Schema Vlaidation Support 
    … …  
    138141                self.warningList = list() 
    139142                self.unresolvedList = list() 
     143                 
     144                # build the blank dom 
     145                self.theDom = None 
    140146         
    141147        def __str__(self): 
    … …  
    174180                return out 
    175181         
    176         def parse(self, inXml): 
     182        def parse(self, inFile): 
    177183                """ 
    178184                Parse - Main work function - Validates the XML, sets the flags and 
    179185                populates the error and warning logs 
    180186                """ 
    181                 # check there is some xml data 
    182                 if len(inXml) == 0: 
    183                         self.errorList.append(ParseMessage(None, None, None, "NoData", None, "No Xml data found")) 
    184                         return 
    185                  
    186                 ## mark xlm as having been parsed 
     187                # mark xlm as having been parsed 
    187188                self.hasParsedXml = True 
    188189                 
    189190                # look at file for Ids, Refs, and namespaces 
    190                 self.scanForIdsAndNamespace(inXml) 
     191                self.scanForIdsAndNamespace(inFile) 
    191192                 
    192193                # check the xml is valid aginst it's schema 
    193                 self.validateAgainstSchema(inXml) 
    194          
    195         def validateAgainstSchema(self, inXml): 
     194                self.validateAgainstSchema() 
     195         
     196        def validateAgainstSchema(self): 
    196197                if not haveXsdSupport: 
    197198                        self.errorList.append(ParseMessage(None, None, None, "XSD", None, " LXML support not available - no validation")) 
    … …  
    201202                schema = self.loadChoosenSchema() 
    202203                # create an IO string for the xml string provided 
    203                 stringXml = StringIO(inXml) 
     204                stringXml = StringIO(self.theDom.toxml()) 
    204205                # building the document tree from the input xml 
    205206                try: 
    … …  
    242243                return schema 
    243244         
    244         def scanForIdsAndNamespace(self, inXml): 
     245        def scanForIdsAndNamespace(self, inFile): 
    245246                ''' 
    246247                Look through the Xml stream for the namespace and store all the ID tags 
    247248                This version looks at all the elements 
    248249                ''' 
    249 #               from xml.sax.handler import feature_namespaces 
    250 #               # Create a parser 
    251 #               parser = make_parser() 
    252 #                
    253 #               # Enable namespace processing 
    254 #               parser.setFeature(feature_namespaces, 1) 
    255                  
     250 
    256251                # locate the handler class to the parser 
    257252                handlerContent = ElementAggregator() 
    … …  
    260255                # the xml in turn 
    261256                try: 
    262                         self.myParseString(inXml, handlerContent, handlerError, True) 
    263                         #sax.parseString(inXml, handlerContent, handlerError) 
     257                        sax.parse(inFile, handlerContent, handlerError) 
    264258                except  sax.SAXParseException: 
    265259                        self.errorList.append(ParseMessage(None, None, None, "XmlError",None, "Parsing of XML failed")) 
    … …  
    274268                # store the namespace 
    275269                self.theNamespace = handlerContent.theNamespace 
    276                  
    277                 print handlerContent.shortFormXml 
    278          
    279         def myParseString(self, inXml, inHandlerContent, inHandlerError, inUseNamespace): 
    280                 parser = sax.make_parser() 
    281                  
    282                 if inUseNamespace: 
    283                         #inHandlerContent.feature_namespace_prefixes = True 
    284                         parser.setFeature(sax.handler.feature_namespaces, True) 
    285                  
    286                 parser.setContentHandler(inHandlerContent) 
    287                 parser.setErrorHandler(inHandlerError) 
    288                  
    289                 inpsrc = sax.xmlreader.InputSource() 
    290                 inpsrc.setByteStream(StringIO(inXml)) 
    291                 parser.parse(inpsrc) 
     270                # store the dom 
     271                self.theDom = handlerContent.dom 
    292272         
    293273        def scanForFirstOmeNamespace(self, inXml): 
    … …  
    323303                # Open the file 
    324304                try: 
    325                         # TODO - stop this loading entire file into memory 
    326305                        theFile = open(inFilename, 'r') 
    327                         theXml = theFile.read() 
     306            # check the file contains some data 
     307                        length = os.stat(inFilename)[ST_SIZE] 
     308                        if length == 0: 
     309                                theFileReport.errorList.append(ParseMessage(inFilename, None, None, "IOFile","", "XML file was of zero length")) 
    328310                except IOError: 
    329311                        theFileReport.errorList.append(ParseMessage(inFilename, None, None, "IOFile","", "XML file could not be read")) 
    330312                        return theFileReport 
    331313                 
    332                 # Look for OME xml element 
    333                  
    334                 # Check for the OME namespace is loaded 
    335                  
    336                 theFileReport.parse(theXml) 
     314                # parse the file into the report and validate it 
     315                theFileReport.parse(theFile) 
    337316                theFileReport.isOmeTiff = False 
     317                # the report has now been populated  
    338318                return theFileReport 
    339319        validateFile = classmethod(validateFile) 
    … …  
    344324                """ 
    345325                theTiffReport = klass() 
     326                # check there is tiff file support 
    346327                if not haveTiffSupport: 
    347328                        theTiffReport.isOmeTiff = False 
    348329                        theTiffReport.errorList.append(ParseMessage(inFilename, None, None, "NoLibrary","", "No Tiff library found - file could not be read")) 
    349330                else: 
     331            # load the tiff image 
    350332                        try: 
    351333                                image = Image.open(inFilename) 
    … …  
    354336                                theTiffReport.errorList.append(ParseMessage(inFilename, None, None, "InvalidFile","", "Not recognised as Tiff format - file could not be read")) 
    355337                        else: 
     338                # check for the XML containing tag within the tiff 
    356339                                if 270 not in image.tag.keys(): 
    357340                                        theTiffReport.isOmeTiff = False 
    358341                                        theTiffReport.errorList.append(ParseMessage(inFilename, None, None, "InvalidTiff","", "Tiff file did not containg an ImageDescription Tag - no XML found")) 
    359342                                else: 
    360                                         xml = image.tag[270] 
     343                                    # read the xml from the tiff 
     344                                        theXml = image.tag[270] 
    361345                                        theTiffReport.isOmeTiff = True 
    362                                         theTiffReport.parse(xml) 
     346                                        # create a file object to represent the xml string 
     347                                        theFileString = StringIO(theXml) 
     348                                        # parse the new string/file object into the report and validate it  
     349                                        theTiffReport.parse(theFileString) 
    363350                return theTiffReport 
    364351        validateTiff = classmethod(validateTiff) 
    … …  
    391378# Used to process all Elements by sax parser 
    392379class ElementAggregator(sax.ContentHandler): 
     380        inBinData = False 
     381         
    393382        def startDocument(self): 
    394383                ''' 
    … …  
    401390                self.shortFormXml = "" 
    402391                self.skipCount = 0 
    403          
    404         def startElementNS(self, name, qname, attribs): 
     392                 
     393                # Setup the DOM chunk 
     394                impl = getDOMImplementation() 
     395                self.dom = impl.createDocument(None, None, None) 
     396                self.stack = list() 
     397         
     398        def startElement(self, name, attribs): 
    405399                ''' 
    406400                Examine each element in turn and harvest any useful information 
    407401                ''' 
    408                 (theElementNamespace, theElementName) = name 
    409                  
    410402                # pull the namespace out of the OME element 
    411                 if theElementName == "OME": 
    412                         if theElementNamespace == None: 
     403                if name == "OME": 
     404                        try: 
     405                                self.theNamespace = attribs.getValue("xmlns") 
     406                        except KeyError: 
    413407                                self.theNamespace = "" 
    414                                 return 
    415                         self.theNamespace = theElementNamespace 
    416408                         
    417409                # save the ID in any elements encountered 
    418                 if theElementName[-3:] == "Ref": 
     410                if name[-3:] == "Ref": 
    419411                        try: 
    420412                                # If a Ref element then save in the refrences 
    421                                 self.references.append(attribs.getValue((None,"ID"))) 
     413                                self.references.append(attribs.getValue("ID")) 
    422414                        except KeyError: 
    423415                                pass 
    … …  
    425417                        try: 
    426418                                # If any other element thee save in the ids 
    427                                 self.ids.append(attribs.getValue((None,"ID"))) 
     419                                self.ids.append(attribs.getValue("ID")) 
    428420                        except KeyError: 
    429421                                pass 
    430  
    431                 # mark start of a BinData element - assumes valid schema 
    432                 if theElementName == "BinData": 
    433                         self.inBinDataContent = True 
    434                         self.skipCount = 0 
     422                                 
     423                if name[-7:] == "BinData": 
     424                        self.inBinData = True 
     425                self.domify(name, attribs) 
    435426                         
    436                 self.shortFormXml = self.shortFormXml + "<%s xmlns=\"%s\"" % (theElementName, theElementNamespace) 
    437                  
    438                 for ((theAttribNamespace, theAttribName), value) in attribs.items(): 
    439                         self.shortFormXml = self.shortFormXml + ' ' + theAttribName + '="' + attribs.getValue((theAttribNamespace,theAttribName)) + '"' 
    440                 self.shortFormXml = self.shortFormXml + '>' 
    441                 for ((attr_ns, lname), value) in attribs.items(): 
    442                         if attr_ns is not None: 
    443                                 attr_qname = attribs.getQNameByName((attr_ns, lname)) 
    444                         else: 
    445                                 attr_qname = lname 
    446                 return 
    447  
    448         def endElementNS(self, name, qname): 
    449                 ''' 
    450                 Record information as element closes 
    451                 ''' 
    452                 (theElementNamespace, theElementName) = name 
    453                 # mark end of a BinData element - assumes valid schema 
    454                 if theElementName == "BinData": 
    455                         self.inBinDataContent = False 
    456                         self.shortFormXml = self.shortFormXml + "Skipped:" 
    457                         self.shortFormXml = self.shortFormXml + str(self.skipCount) 
    458                 self.shortFormXml = self.shortFormXml + '</' + theElementName + '>' 
    459          
    460         def characters(self, ch): 
    461                 ''' 
    462                 Copy each character in turn or count if skipped 
    463                 ''' 
    464                 if self.inBinDataContent: 
    465                         self.skipCount = self.skipCount + len(ch) 
     427        def endElement(self, name): 
     428                newElement = self.stack.pop() 
     429                length = len(self.stack) 
     430                if length == 0: 
     431                        self.dom.appendChild(newElement) 
    466432                else: 
    467                         self.shortFormXml = self.shortFormXml + ch 
    468          
     433                        self.stack[-1].appendChild(newElement) 
     434                self.clear()     
     435 
     436        def domify(self, name, attribs): 
     437                newElement = self.dom.createElement(name) 
     438                for (attr, value) in attribs.items(): 
     439                        newAttribute = self.dom.createAttribute(attr) 
     440                        newAttribute.value = value 
     441                        newElement.setAttributeNode(newAttribute) 
     442                self.stack.append(newElement) 
     443                 
     444        def characters(self, content): 
     445                if not self.inBinData: 
     446                        # Strip trailing and/or leading whitespace, "\n", "\r", etc. 
     447                        content = content.strip().strip('\n\r') 
     448                        if len(content) > 0 and len(self.stack) > 0: 
     449                                textNode = self.dom.createTextNode(content) 
     450                                self.stack[-1].appendChild(textNode) 
     451                 
     452        def clear(self): 
     453                self.inBinData = False 
    469454 
    470455# Used to process the Elements until a namespace is found by sax parser 

Download in other formats:

  • Unified Diff
  • Zip Archive

Trac Powered

Powered by Trac 0.11
By Edgewall Software.

Visit the Trac open source project at
http://trac.edgewall.org/