Italian community of Lazarus and Free Pascal

Programmazione => Databases => Topic aperto da: Legolas - Aprile 16, 2013, 03:44:53 pm

Titolo: XML: da dove cominciare?
Inserito da: Legolas - Aprile 16, 2013, 03:44:53 pm
Ciao a tutti! E' da un po' che non mi faccio vivo, anche se continuo a lurkare selvaggiamente nell'ombra  ;D
Vengo al dunque: sono alle prese con la pianificazione di un progettino che ho in mente da tempo e che vede la necessità di utilizzare un grosso file XML (sui 15 mega) dal quale estrapolare dei dati in un determinato ordine, secondo determinate condizioni. I dati estrapolati verranno ricombinati e dati in pasto a TeX per tirarne fuori un corposo documento da mandare in stampa.

Problemi: 1) il file XML dal quale devo estrapolare i dati è in codifica UTF-8, 2) ha una struttura zeppa di sottonodi e, soprattutto, 3) non so una mazza di XML  :D

Qualcuno pratico mi illumina sulle possibilità di Laz/fpc di gestire XML e sulle problematiche della codifica UTF-8?  :)
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 16, 2013, 04:14:29 pm
Allora UTF-8 o meno, usa il TXMLDocument di lazarus ...
Si arrangia lui a leggere.
Per l'estrazione dei noti d'interesse suggerire XPATH.
XMLRead, XMLWrite contengono le routine per leggere e scrivere XML ;)

Poi per i dettagli di come muoversi, bisogna conoscere la struttura dell'XML.
Se usa o meno i gli attributi o è tutto nodi anche quando non servono :D

Stilgar
Titolo: Re:XML: da dove cominciare?
Inserito da: nomorelogic - Aprile 16, 2013, 04:24:02 pm
con un XML di 15 mb potrebbe anche essere pesante andare a lavorare con DOM
se i tempi diventano inaccettabili c'è anche un approccio SAX che occupa molte meno risorse del DOM però è meno elastico
se dovesse servire mi ridocumento ;)

UTF-8 non è altro che un tipo di rappresenzazione di file unicode.
unicode completo è a 32 bit (già: 4 byte per ogni carattere)... se il tuo file non fosse UTF-8 ti troveresti a lavorare con un file di 60MB :)

UFT-8 ha in comune con un normale file ASCII i primi 127 caratteri (quelli con bit nr. 8 impostato a 0) e quindi se il tuo file di dati lavora in questo range puoi pensarlo come un normale file ascii.
se hai bisogno di un carattere sopra ai 127, l'8° bit è impostato ad 1 e vuol dire che segue un altro carattere sempre riferito a quello precedente (a cui deve essere concatenato per ottenere il vero carattere unicode).
questa cosa è ricorsiva fino a 4 byte (credo)
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 16, 2013, 04:31:46 pm
Per prima cosa grazie! Sapevo che avrei avuto le prime risposte in una manciata di minuti  :D

@Stilgar: il file XML utilizza gli attributi... E' grave?  ;D

@nomorelogic: purtroppo devo utilizzare caratteri al di sopra (molto al di sopra!) dei 127. Si tratta di Kanji, per chi mastica giapponese  :)

Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 16, 2013, 06:08:00 pm
No ... anzi ... meglio se usa gli attributi...
XPATH ti farà estrarre i dati in modo più comodo ;)

Poi mi spieghi come mai sei incasinato con il Kanji :p
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 16, 2013, 10:11:42 pm
Oh... ok, meglio così, allora  :D
Ho provato a cercare qualche riferimento su XPATH, ma non si trova praticamente niente. Un esempietto minimo per capire?  :)

Nel caso servisse, qui sotto ho allegato un estratto minimo del mio file xml. Quello che dovrei fare è scorrere  tutti i nodi character e, se il sottonodo dic_number->dic_ref, contenente uno specifico dr_type (ad esempio ="nelson_c"), contiene un valore minore di X, allora devo leggere il valore del nodo literal (e di altri, ma quello verrà dopo, non appena riesco a capirci qualcosa  :P ) e salvarlo.

Sul perché/percome del progetto che ho in mente, basti sapere che sono un giappofilo della prima ora e sto sbattendo la testa sui kanji per impararne un quantitativo minimo per cominciare a studiare la lingua più seriamente  :o
Titolo: Re:XML: da dove cominciare?
Inserito da: bonmario - Aprile 17, 2013, 08:09:00 am
Ciao,
come ti consigliava nomorelogic, secondo me la prima cosa che devi valutare e se leggere l'XML con DOM o con SAX.
La differenza principale tra i 2, che di solito mi fa optare per l'uno o per l'altro, è che DOM legge tutto l'XML e lo mette in memoria, così poi lo puoi elaborare come se fosse un albero, andando avanti e tornando indietro a piacimento. SAX invece, legge l'XML poco alla volta e, quando si presenta un nuovo tag, un nuovo attributo, eccetera, fa scattare l'evento corrispondente.
Se per esempio tu devi leggere il tuo file ed uscire al primo tag che trovi con dentro "pippo", la cosa migliore sarebbe leggere l'XML con SAX. Se invece devi continuare a fare avanti e indietro per i vari tag, attributi eccetera, l'ideale è DOM.

Ciao, Mario
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 17, 2013, 10:01:52 am
Uhm... non so... il mio file ha almeno 15000 "record" (perdonatemi il termine improprio), ognuno formato da svariati "campi". D'altro canto non ho tutto questo bisogno di ottimizzare (il tool non verrà rilasciato al pubblico, ma utilizzato solo da me). Credo che in fin dei conti potrebbe essermi sufficiente una lettura sequenziale, visto che devo scansionare tutti i "record" e "piluccare" quelli che soddisfano determinati criteri.
SAX potrebbe essere una scelta, ma aspetto maggiori delucidazioni su XPATH  ;)
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 17, 2013, 10:43:07 am
Se vuoi ottenere tutti i nodi dell'xml che abbiano un dic_ref di un certo tipo ... (magari l'attributo dr_type="nelson_c") l'espressione xpath che ti server è qualche cosa del tipo:
Codice: [Seleziona]
//dic_ref[@dr_type='nelson_c']
in questo caso ottieni tutti i nodi che abbiano quel determinato attributo in una lista.
nel caso tu volessi filtrare ancora per il contenuto del nodo trovato
Codice: [Seleziona]
//dic_ref[dr_type="nelson_c"]/text()="4985"

Sono esempi a memoria...
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 17, 2013, 10:51:26 am
Grazie mille :)

Appena ho modo, faccio qualche tentativo e vi faccio sapere  ;)
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 17, 2013, 11:13:46 am
Un plug per Firefox :
http://code.google.com/p/xpathchecker/
Puoi verificare l'xpath senza diventare matto.
Io lo uso anche per lavoro :D
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 17, 2013, 11:22:18 am
Piccolo consiglio:
 tieni conto che i processori XPATH lavorano ad insiemi (liste nel nostro caso)
Quindi prendono in considerazione ogni "step" (definiti da "/") e processano i nodi.
In altre parole.
//dic_ref[@dr_type='nelson_c']
//dic_ref -> /Tutti i nodi a qualsiasi livello/solo quelli dic_ref
di questi ottenuti, fa un secondo giro:
quelli che hanno attributo dr_type con valore 'nelson_c'.
In pratica lavora su una lista che viene via via scremata.
Per avere un minimo di "prestazioni" cerca di filtrare sempre il grosso con i primi step, in modo che i controlli sucessivi siano su liste già piccoline ;)
Stilgar
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 18, 2013, 12:19:15 pm
Sto facendo qualche prova  :)
Premetto che ho cercato qualcosa anche per SAX, ma non sono riuscito a trovare esempi/guide di utilizzo.
Per quanto riguarda xpath, ci sto giocando un pochino prima di cimentarmi nella stesura del codice. Quello che non riesco a capire è come filtrare i risultati in base a criteri "matematici". Esempio: poniamo che debba filtrare tutti i dati in cui il valore dell'attributo dr_type='nelson_c' sia < 100. Provo a scrivere qualcosa del tipo:

Codice: xpath [Seleziona]

/kanjidic2/character[//dic_ref[@dr_type='nelson_c']<100]


ma il filtro sembra non funzionare. Dove sbaglio? E nel caso volessi inserire condizioni multiple?  ???
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 18, 2013, 12:41:45 pm
/kanjidic2/character//dic_ref[@dr_type='nelson_c']
Per la selezione del "livello" del nodo.
(ridondante rispetto a //dic_ref[@dr_type='nelson_c'])


www.w3schools.com/xpath

/kanjidic2/character//dic_ref[@dr_type='nelson_c']<100
o
//dic_ref[@dr_type='nelson_c']<100
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 18, 2013, 12:58:44 pm
(Ho provato ... c'è solo un match)
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 18, 2013, 01:46:08 pm
Ok, ma così XPathChecker mi tira fuori solo un "true" ad indicare che ha trovato nodi che soddisfano la condizione. Se volessi prendere i dati da quei nodi, ad esempio /literal?
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 18, 2013, 01:49:02 pm
hai ragione ... ma è un tool da usare per "controllo" dell'xpath come espressione ;)

EDIT:
Al posto di dire alla libreria che vuoi i valori, le chiedi i nodi ... così non hai il problema...
Se vuoi preparo una prova in pascal.

Stilgar
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 18, 2013, 02:01:29 pm
hai ragione ... ma è un tool da usare per "controllo" dell'xpath come espressione ;)

Dal nome XPathChecker  il dubbio doveva venirmi  ;D

Citazione
EDIT:
Al posto di dire alla libreria che vuoi i valori, le chiedi i nodi ... così non hai il problema...
Se vuoi preparo una prova in pascal.

Stilgar

Ma magari!  :D
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 18, 2013, 02:34:53 pm
L'espressione che volevi ... quella completa era :
Codice: [Seleziona]
//dic_ref[@dr_type='nelson_c']/.[text()<100]
Ma così non vale ... ;)
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 18, 2013, 02:53:09 pm
Ok, grazie mille! Forse ci siamo quasi!

Codice: xpath [Seleziona]
/kanjidic2/character[dic_number[dic_ref[@dr_type='nelson_c']/.[text()<100 and text()>42]]]


Questo "coso" qui sopra filtra l'xml nel modo in cui serve a me, restituendomi tutti i nodi figli di character. Da questa lista posso quindi prendere i dati che mi servono (tipo il kanji con literal, i significati in diverse lingue con meaning, ecc.).
Mi resta quindi da vedere come funziona la unit xpath e vedere se è UTF-8 compliant...  :D
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 18, 2013, 02:58:17 pm
La libreria pascal mi da un'errore nel riconoscimento dell'espressione... o.O
Codice: [Seleziona]
 variable := EvaluateXPathExpression(
      '//dic_ref[@dr_type="nelson_c"]/.[number(text())<100]', FDom);
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 18, 2013, 03:44:36 pm
Ecco...  ::)

Da quello che leggo in giro (http://bugs.freepascal.org/view.php?id=22470), la unit xpath non dovrebbe nemmeno supportare UTF-8, tra l'altro  :(

A questo punto non mi rimane che provare con SAX (o DOM, al limite), con tutti i problemi di cui sopra

EDIT:
intanto ho trovato qualcosa con cui "giocherò" stasera
http://www.benibela.de/sources_en.html#internettools  :)
Titolo: Re:XML: da dove cominciare?
Inserito da: El Salvador - Aprile 18, 2013, 04:46:27 pm
Citazione
Da quello che leggo in giro, la unit xpath non dovrebbe nemmeno supportare UTF-8, tra l'altro
Le librerie di FPC 2.6.x sono ancora ANSI, mentre LCL (e quindi Lazarus) utilizza UTF8. Se non mi sbaglio, UTF-8 arriverà su FPC con la versione 2.7.x.
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 18, 2013, 04:58:50 pm
Sì, fcl-xml è stata convertita (dovrebbero essere le unit col prefisso "laz_", tipo Laz_DOM, Laz_xmlread, ecc.). Manco a dirlo, l'unica che manca è proprio xpath... 
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 18, 2013, 05:04:54 pm
Legolas, fammi sapere come vanno i test ;)
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 20, 2013, 04:59:26 pm
E niente, alla fine ho usato DOM plain vanilla  ;D
Magari ci sono metodi più ortodossi/veloci/eleganti, ma alla fine a me serve ottenere il risultato e amen. Ovviamente utilizzo le unit laz2_* per il supporto a UTF-8.

Grazie a tutti per i consigli  ;)
Titolo: Re:XML: da dove cominciare?
Inserito da: Stilgar - Aprile 20, 2013, 05:08:30 pm
mmmm. Ma usare le funzione SystemToUTF8 e UTF8ToSystem non ti erano sufficenti?
Strano ;)
A volte basta avere il risultato anche se brutto e sporco ;)

Stilgar
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 20, 2013, 07:05:53 pm
Probabilmente sì, ma così senza sbattermi troppo, 4 righe in croce di codice e ottengo quello che mi serve  :D
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 20, 2013, 09:57:09 pm
Rieccomi qui...

Ho buttato giù un veloce programmino che mi filtra i kanji secondo i miei criteri. Il file xml viene scorso correttamente e ottengo i risultati attesi, fino ad un determinato carattere:
𠀋 (http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=2000B&useutf8=true)

Su questo carattere (e anche su altri) becco un SIGSEGV. L'unica cosa che ho notato è che questo kanji, nell'editor "Sublime Text 2" sembra occupare 2 caratteri. Provo a spiegarmi: posizionando il cursore prima del carattere, bisogna premere il tasto cursore destro per due volte, perché con una singola pressione si ferma nel mezzo del kanji  :o
In pratica, tutti i kanji che hanno una codifica Unicode superiore a $20000 hanno lo stesso comportamento...

Idee?
 
Titolo: Re:XML: da dove cominciare?
Inserito da: bonmario - Aprile 21, 2013, 07:16:53 am
Ciao,
se non ricordo male, per poter definire tutti i caratteri dell'alfabeto cinese, e forse anche per quello giapponese, serve l'UTF16.
Comunque, se cerchi un po' in giro, se non c'è qualcosa di già pronto, dovrebbe essere abbastanza semplice fare la ricodifica. L'unico "problema" è che devi leggere la stringa un carattere alla volta e, se il carattere letto è uno di quelli particolari, non lo devi emettere subito, ma devi leggere anche il successivo.

Ciao, Mario
Titolo: Re:XML: da dove cominciare?
Inserito da: nomorelogic - Aprile 21, 2013, 11:14:25 am
UTF-8 a differenza di UTF-16 e UTF-32 ha una codifica variabile: non tutti i caratteri vengono rappresentati con lo stesso numero di byte.

secondo me quel carattere che è rappresentato da 2 byte ha il primo byte con il bit più alto impostato ad 1 questo vuol dire che ne deve seguire un altro.  Il secondo byte dovrebbe avere il bit più alto impostato a zero per indicare che è l'ultimo byte da prendere in considerazione.

Tutti quelli che si comportano correttemente (1 char = 1 byte) dovrebbero avere il bit più alto a 0.
Questo almeno è quello che ricordo a memoria, ma non ho mai avuto modo di sbatterci il muso :P
Mi farebbe tanto piacere sapere se è effettivamente così :)
Titolo: Re:XML: da dove cominciare?
Inserito da: Legolas - Aprile 21, 2013, 11:21:15 am
In effetti è una questione di rappresentazione  :)

http://it.wikipedia.org/wiki/UTF-16#Procedura_di_codifica_UTF-16 (http://it.wikipedia.org/wiki/UTF-16#Procedura_di_codifica_UTF-16)

Alla fine credo che tralascerò quei caratteri, perché non rientrano nel range di cui ho bisogno. Magari in futuro proverò a rimetterci mano, ma per il momento mi basta sapere dov'è il problema  ;)