Topic: sax e handler  (Letto 1511 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline nkint

  • python neanderthalensis
  • ****
  • Post: 368
  • Punti reputazione: 1
    • Mostra profilo
sax e handler
« il: Febbraio 28, 2011, 18:20 »
ciao a tutti,
devo soltanto parsare quindi sto usando un parser sax, da quel che ho capito è più veloce di dom

il mio xml è una cosa del genere:
[codice]<OpenSearchDescription xmlns:opensearch="blablabla">
  <opensearch:totalResults>1</opensearch:totalResults>
  <movies>
    <movie>
      <translated>true</translated>
      <language>en</language>
      <type>movie</type>
      <id>4</id>
      <votes>3</votes>
      <rating>8.0</rating>
      <last_modified_at>2011-02-28 05:23:39</last_modified_at>
    </movie>
  </movies>
</OpenSearchDescription>
[/codice]

ora io devo controllare prima che sia nel db (con il suo id e il suo type) e se last_modified_at è più recente.. aggiornarlo

con sax come fare?
ho soltato i metodi startElement, characters, endElement.. e ho pensato: mi creo dei flag temporanei appena entro in un element, se è id o type o last_modified.. aggiorno il flag. quando ho finito.. controllo il flag.
un po' troppo macchinoso: funziona, ma sinceramente mi sembra una schifezza

[codice]   class QueryAlreadyInDatabase_Handler(ContentHandler):
      def startElement(self, name, attr):      
         #print 'start: ', name, attr
         if name=='type': self._type = ''
         if name=='id': self._id = ''
         if name=='last_modified_at': self._date = ''
      def characters(self, content):
         if hasattr(self, '_type'): self._type += content
         elif hasattr(self, '_id'): self._id += content
         elif hasattr(self, '_date'): self._date += content
      def endElement(self, name):
         if name=='type':
            self.type = str(self._type)
            del self._type
         elif name=='id':
            self.n = int(self._id)
            del self._id
         elif name=='last_modified_at':
            self.date = str(self._date)
            del self._date

         if hasattr(self, 'type') and hasattr(self, 'n') and hasattr(self, 'date'):
            print '-------------------------', self.type, self.n, self.date
[/codice]

certo potrei renderlo un po' più dinamico e dargli un __init__ del tipo:

QueryAlreadyInDatabase_Handler(['type', 'id', 'last_modified_at']

ma il concetto è quello..


dopo che ho controllato che effettivamente sia da aggiornare.. farei un'altra passata per prendere tutti i tag e avere la query di update..
magari con questo snippet:
http://code.activestate.com/recipes/534109-xml-to-python-data-structure/
« Ultima modifica: Febbraio 28, 2011, 18:22 da nkint »

Offline riko

  • python deus
  • *
  • moderatore
  • Post: 7.453
  • Punti reputazione: 12
    • Mostra profilo
    • RiK0 Tech Temple
Re: sax e handler
« Risposta #1 il: Febbraio 28, 2011, 19:21 »
elementtree e' tuo amico...

Offline nkint

  • python neanderthalensis
  • ****
  • Post: 368
  • Punti reputazione: 1
    • Mostra profilo
Re: sax e handler
« Risposta #2 il: Febbraio 28, 2011, 20:40 »
EDIT: ma elementtree è sax o pull? inizialmente ci avevo dato un occhio ma l'avevo classificato intuitivamente come dom

che bomba elementtree!

però..
Citazione
e.findtext("opensearch:totalResult")

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/xml/etree/ElementTree.py", line 632, in findtext
    return self._root.findtext(path, default)
  File "/usr/lib/python2.6/xml/etree/ElementTree.py", line 344, in findtext
    return ElementPath.findtext(self, path, default)
  File "/usr/lib/python2.6/xml/etree/ElementPath.py", line 192, in findtext
    return _compile(path).findtext(element, default)
  File "/usr/lib/python2.6/xml/etree/ElementPath.py", line 176, in _compile
    p = Path(path)
  File "/usr/lib/python2.6/xml/etree/ElementPath.py", line 93, in __init__
    "expected path separator (%s)" % (op or tag)
SyntaxError: expected path separator (:)
« Ultima modifica: Febbraio 28, 2011, 20:57 da nkint »

Offline riko

  • python deus
  • *
  • moderatore
  • Post: 7.453
  • Punti reputazione: 12
    • Mostra profilo
    • RiK0 Tech Temple
Re: sax e handler
« Risposta #3 il: Febbraio 28, 2011, 21:30 »
EDIT: ma elementtree è sax o pull? inizialmente ci avevo dato un occhio ma l'avevo classificato intuitivamente come dom

E' se stesso! Comunque puoi anche usare delle query xpath, che sono probabilmente quello che ti serve davvero.

Offline nkint

  • python neanderthalensis
  • ****
  • Post: 368
  • Punti reputazione: 1
    • Mostra profilo
Re: sax e handler
« Risposta #4 il: Febbraio 28, 2011, 22:13 »
mhmm no alla fine findall mi va benissimo per fare il mio parsing, xpath magari mi serve più avanti grazie

il problema è che il mio xml inizia con
[codice]<opensearch:totalResults>1</opensearch:totalResults> [/codice]

e se provo (sia findallc he xpath) a usare "opensearch:totalResults" dice che non gli vanno bene i ':'
in realtà potrei anche cercarlo con una banalissima regexp tanto devo solo matchare che numero c'è prima di andare avanti..

EDIT: vabeh ho risolto girandoci attorno, ottimo l'elementtree.findall!
« Ultima modifica: Febbraio 28, 2011, 22:39 da nkint »

Offline riko

  • python deus
  • *
  • moderatore
  • Post: 7.453
  • Punti reputazione: 12
    • Mostra profilo
    • RiK0 Tech Temple
Re: sax e handler
« Risposta #5 il: Febbraio 28, 2011, 23:30 »
occhio ai namespace...