class UploadXMLHandler(DefaultHandler2): """Класс SAX-парсера, производящий разбор xml и вставку данных в таблицу""" parentTag = None currentCell = None flag = 0 currentString = u'' currentEncoding = u"utf8" def __init__(self, tableInstance, action): self.tableInstance = tableInstance # возможность настраивать, нужно ли обновлять записи и вставлять новые def actionUI(ins): if not ins.tryInsert(): ins.update() def actionU(ins): ins.tryUpdate() def actionI(ins): ins.tryInsert() # определяем, какую функцию нам нужно использовать self.funcAction = locals()['action%s' % action.upper()] def startElement(self, namespaceURI, lname, qname, attrs): if self.parentTag == 'field': if self.flag == 0: self.stringWriter = StringWriter() self.xmlWriter = XMLOutputFactory.newInstance( ).createXMLStreamWriter(self.stringWriter, "UTF-8") self.flag += 1 self.xmlWriter.writeStartElement(qname) for i in range(0, attrs.getLength()): self.xmlWriter.writeAttribute(attrs.getQName(i), attrs.getValue(i)) elif qname == 'table' and self.flag == 0: if self.parentTag is not None: raise CelestaException(u"Неверный формат файла") self.parentTag = qname if not attrs.getValue('name'): raise CelestaException( u"Атрибут 'name' отсутствует в теге 'table'") elif attrs.getValue('name') != self.tableInstance.meta().getName(): raise CelestaException( u"Имя таблицы %s не соответствует значению атрибута 'name'" % self.tableInstance.meta().getName()) elif qname == 'row' and self.flag == 0: if self.parentTag != 'table': raise CelestaException(u"Неверный формат файла") self.parentTag = qname elif qname == 'field' and self.flag == 0: if self.parentTag != 'row': raise CelestaException(u"Неверный формат файла") self.currentEncoding = attrs.getValue('encoding') or u"utf8" self.currentCell = attrs.getValue('name') self.parentTag = qname self.currentString = u'' else: raise CelestaException(u"Неверный формат файла") def endElement(self, uri, lname, qname): if qname == 'table' and self.flag == 0: self.parentTag = None elif qname == 'row' and self.flag == 0: # обновляем или вставляем записи self.funcAction(self.tableInstance) self.tableInstance.clear() self.parentTag = 'table' elif qname == 'field' and self.flag == 0: # Вставка данных в поле таблицы, отдельно рассмотрен случай если данные в формате XML if hasattr(self, 'stringWriter') and self.stringWriter: self.xmlWriter.close() # Вставка данных в поле типа blob if self.tableInstance.meta().columns[ self.currentCell].getCelestaType() == 'BLOB': getattr(self.tableInstance, "calc%s" % self.currentCell)() blobField = self.tableInstance.__dict__[ self.currentCell].getOutStream() blobField.write(self.stringWriter.strip()) else: self.tableInstance.__setattr__( self.currentCell, self.stringWriter.toString()) self.stringWriter.flush() self.stringWriter = None self.xmlWriter = None else: # проверка на None if self.currentString.strip() != 'None': self.currentString = self.currentString.strip() # Вставка данных в поле типа blob if self.tableInstance.meta().columns[ self.currentCell].getCelestaType() == 'BLOB': getattr(self.tableInstance, "calc%s" % self.currentCell)() blobField = self.tableInstance.__dict__[ self.currentCell].getOutStream() if self.currentEncoding == u"utf8": blobField.write(self.currentString) elif self.currentEncoding == u"base64": blobField.write( base64.b64decode(self.currentString)) else: raise CelestaException(u"Неверная кодировка") elif self.tableInstance.meta().columns[ self.currentCell].getCelestaType() == 'DATETIME': sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") self.tableInstance.__setattr__( self.currentCell, sdf.parse(self.currentString)) elif self.tableInstance.meta().columns[ self.currentCell].getCelestaType() == 'BIT': self.tableInstance.__setattr__( self.currentCell, self.currentString.lower() == "true") else: if self.currentCell == 'prefix': pass self.tableInstance.__setattr__(self.currentCell, self.currentString) self.parentTag = 'row' self.currentCell = None self.currentString = None elif self.parentTag == 'field': self.xmlWriter.writeEndElement() self.flag -= 1 def characters(self, ch, start, length): if self.parentTag == 'field' and self.flag > 0: self.xmlWriter.writeCharacters(ch, start, length) elif self.currentCell: self.currentString += unicode(String(ch[start:start + length])) def comment(self, ch, start, length): if self.parentTag == 'field' and self.flag > 0: self.xmlWriter.writeComment(ch.tostring()[start:start + length]) def startPrefixMapping(self, prefix, uri): if self.parentTag == 'field' and self.flag > 0: if prefix == "": self.xmlWriter.setDefaultNamespace(uri) else: self.xmlWriter.setPrefix(prefix, uri) def processingInstruction(self, target, data): if self.parentTag == 'field' and self.flag > 0: self.xmlWriter.writeProcessingInstruction(target, data) def skippedEntity(self, name): if self.parentTag == 'field' and self.flag > 0: self.xmlWriter.writeEntityRef(name)