--- ZSQLExtend/importFMPXML.py 2011/06/23 09:14:53 1.33 +++ ZSQLExtend/importFMPXML.py 2012/02/15 08:08:42 1.34 @@ -9,7 +9,8 @@ import time import re from xml import sax -from amara import saxtools +from xml.sax.handler import ContentHandler +#from amara import saxtools try: import psycopg2 as psycopg @@ -125,7 +126,7 @@ class TableColumn: return self.name -class xml_handler: +class xml_handler(ContentHandler): def __init__(self,options): """SAX handler to import FileMaker XML file (FMPXMLRESULT format) into the table. @param options: dict of options @@ -151,13 +152,15 @@ class xml_handler: # set up parser + self.result={} self.event = None - self.top_dispatcher = { - (saxtools.START_ELEMENT, fm_ns, u'METADATA'): - self.handle_meta_fields, - (saxtools.START_ELEMENT, fm_ns, u'RESULTSET'): - self.handle_data_fields, - } + +# self.top_dispatcher = { +# (saxtools.START_ELEMENT, fm_ns, u'METADATA'): +# self.handle_meta_fields, +# (saxtools.START_ELEMENT, fm_ns, u'RESULTSET'): +# self.handle_data_fields, +# } # connect database self.dbCon = psycopg.connect(options.dsn) @@ -193,6 +196,8 @@ class xml_handler: self.dbIDs = {} self.rowcnt = 0 + self.currentName = None + if self.id_field is not None: # prepare a list of ids for sync mode qstr="select %s from %s"%(self.id_field,self.table) @@ -212,27 +217,67 @@ class xml_handler: return - def handle_meta_fields(self, end_condition): - dispatcher = { - (saxtools.START_ELEMENT, fm_ns, u'FIELD'): - self.handle_meta_field, - } + def startElement(self, name, attrs): + logging.debug(name) + if (name.lower() == "field") : + self.handle_meta_field(attrs) + if (name.lower() == "row") : + logging.debug("handleROW") + self.handle_row(attrs) + if (name.lower()=="resultset"): + self.handle_data_fields(attrs) + + if (name.lower()=="data"): + self.handle_data_tag(attrs); + + def endElement(self,name): + if (name.lower() == "resultset") : + self.currentTag="" + self.handle_end_data_fields() + if (name.lower() == "field") : + self.handle_end_meta_field() + if (name.lower() == "metadata"): + self.handle_end_meta_fields() + if (name.lower() == "row") : + logging.debug("handleROW") + self.handle_end_row() + + if (name.lower() == "col") : + self.handle_end_col() + def characters(self,content): + + try: + fn = self.xml_field_names[self.colIdx] + self.xml_data[fn] = content + except: + logging.debug(content) + pass + +# if self.currentName is not None: +# logging.debug(self.currentName+" "+content) +# self.currentRow[self.currentName]=content; +# + def handle_end_meta_fields(self): +# dispatcher = { +# (saxtools.START_ELEMENT, fm_ns, u'FIELD'): +# self.handle_meta_field, +# } #First round through the generator corresponds to the #start element event - self.logger.info("reading metadata...") - if self.debug_data: - self.logger.debug("START METADATA") - yield None +# self.logger.info("reading metadata...") +# if self.debug_data: +# self.logger.debug("START METADATA") +# #yield None #delegate is a generator that handles all the events "within" #this element - delegate = None - while not self.event == end_condition: - delegate = saxtools.tenorsax.event_loop_body( - dispatcher, delegate, self.event) - yield None - - #Element closed. Wrap up +# delegate = None +# while not self.event == end_condition: +# delegate = saxtools.tenorsax.event_loop_body( +# dispatcher, delegate, self.event) +# yield None +# +# #Element closed. Wrap up if self.debug_data: self.logger.debug("END METADATA") @@ -360,10 +405,13 @@ class xml_handler: self.logger.debug("add-query: "+self.addQuery) return - def handle_meta_field(self, end_condition): - name = self.params.get((None, u'NAME')) - yield None + def handle_meta_field(self, attrs): + self.currentName = attrs.get('NAME') + #yield None + return + def handle_end_meta_field(self): #Element closed. Wrap up + name = self.currentName if self.lc_names: # clean name sqlname = sqlName(name) @@ -376,27 +424,20 @@ class xml_handler: self.logger.debug("FIELD name: "+name) return - def handle_data_fields(self, end_condition): - dispatcher = { - (saxtools.START_ELEMENT, fm_ns, u'ROW'): - self.handle_row, - } + def handle_data_fields(self, attrs): + #First round through the generator corresponds to the #start element event self.logger.info("reading data...") if self.debug_data: self.logger.debug("START RESULTSET") self.rowcnt = 0 - yield None + return + def handle_end_data_fields(self): #delegate is a generator that handles all the events "within" #this element - delegate = None - while not self.event == end_condition: - delegate = saxtools.tenorsax.event_loop_body( - dispatcher, delegate, self.event) - yield None - + #Element closed. Wrap up if self.debug_data: self.logger.debug("END RESULTSET") @@ -437,24 +478,18 @@ class xml_handler: return def handle_row(self, end_condition): - dispatcher = { - (saxtools.START_ELEMENT, fm_ns, u'COL'): - self.handle_col, - } + if self.debug_data: self.logger.debug("START ROW") self.xml_data = {} self.colIdx = 0 - yield None + return + + def handle_end_row(self): #delegate is a generator that handles all the events "within" #this element - delegate = None - while not self.event == end_condition: - delegate = saxtools.tenorsax.event_loop_body( - dispatcher, delegate, self.event) - yield None - + #Element closed. Wrap up if self.debug_data: self.logger.debug("END ROW") @@ -489,7 +524,7 @@ class xml_handler: continue f = self.xml_field_map[fn] - val = self.xml_data[fn] + val = self.xml_data.get(fn,None) type = self.sql_fields[f.getName()].getType() if type == "date" and len(val.strip()) == 0: # empty date field @@ -539,37 +574,25 @@ class xml_handler: return - def handle_col(self, end_condition): - dispatcher = { - (saxtools.START_ELEMENT, fm_ns, u'DATA'): - self.handle_data_tag, - } - #print "START COL" - yield None - #delegate is a generator that handles all the events "within" - #this element - delegate = None - while not self.event == end_condition: - delegate = saxtools.tenorsax.event_loop_body( - dispatcher, delegate, self.event) - yield None - #Element closed. Wrap up - #print "END COL" + def handle_end_col(self): + + self.colIdx += 1 return - def handle_data_tag(self, end_condition): + + def handle_data_tag(self, attrs): #print "START DATA" - content = u'' - yield None - # gather child elements - while not self.event == end_condition: - if self.event[0] == saxtools.CHARACTER_DATA: - content += self.params - yield None - #Element closed. Wrap up - fn = self.xml_field_names[self.colIdx] - self.xml_data[fn] = content + self.content = u'' +# yield None +# # gather child elements +# while not self.event == end_condition: +# if self.event[0] == saxtools.CHARACTER_DATA: +# content += self.params +# yield None +# #Element closed. Wrap up +# fn = self.xml_field_names[self.colIdx] +# self.xml_data[fn] = content return @@ -609,10 +632,10 @@ def importFMPXML(options): #The "consumer" is our own handler consumer = xml_handler(options) #Initialize Tenorsax with handler - handler = saxtools.tenorsax(consumer) + #handler = saxtools.tenorsax(consumer) #Resulting tenorsax instance is the SAX handler - parser.setContentHandler(handler) - parser.setFeature(sax.handler.feature_namespaces, 1) + parser.setContentHandler(consumer) + #parser.setFeature(sax.handler.feature_namespaces, 1) parser.parse(options.filename)