View Full Version : [Python] Parsing di un file xml
Sick Boy
30-09-2008, 13:10
ciao a tutti,
un'applicazione mi fornisce in output un file (ad esempio chiamato xml.dump) di cui dovrei fare un parsing tramite python in modo da potere processare i suoi diversi tag.
ho importato il modulo minidom correttamente, ma quando eseguo la linea di codice:
minidom.parse('C:\\xml.dump')
mi da questo errore
Traceback (most recent call last):
File "<pyshell#147>", line 1, in -toplevel-
minidom.parse('C:\\xml.dump')
File "C:\Python23\lib\xml\dom\minidom.py", line 1915, in parse
return expatbuilder.parse(file)
File "C:\Python23\lib\xml\dom\expatbuilder.py", line 924, in parse
result = builder.parseFile(fp)
File "C:\Python23\lib\xml\dom\expatbuilder.py", line 207, in parseFile
parser.Parse(buffer, 0)
ExpatError: junk after document element: line 66, column 0
da cosa deriva questo problema e come posso rislverlo?
grazie
cdimauro
30-09-2008, 13:28
Non ho mai usato il miniDOM parser, ma xml.parsers.expat.
Comunque posta il file xml.dump (io lo chiamerei dump.xml :D), così possiamo fare qualche prova. :)
Sick Boy
30-09-2008, 13:37
anche io lo rinominerei *.xml, ma l'applicazione che fa il dump a ora mi consegna un file con quell'estensione.
il contenuto del file non è importante. anche con un file xml base mi da gli stessi problemi! forse il problema è dipendente dal contenuto delle parentesi (non so se è corretto scrivere il percorso intero del file)
Sick Boy
30-09-2008, 13:50
ho provato a usare xml.parsers.expat e ho risultati migliori, anche se dopo queste righe di codice:
>>> import xml.parsers.expat
>>> p = xml.parsers.expat.ParserCreate()
>>> docxml = p.Parse('xml-001322.dump')
>>> print docxml
mi stampa a video: 1
cdimauro
30-09-2008, 13:58
Io lo uso così:
self.p = xml.parsers.expat.ParserCreate()
self.p.buffer_text = True
self.p.returns_unicode = False
self.p.StartElementHandler = self.start_element
self.p.EndElementHandler = self.end_element
self.p.CharacterDataHandler = self.char_data
e funziona perfettamente.
All'interno di una classe, ovviamente.
Gli handler sono metodi della classe (ma possono anche essere funzioni esterne).
Sick Boy
30-09-2008, 14:19
in che classe hai messo tutto questo?
e poi come faresti la chiamata al fantomatico xml.dump?
cdimauro
30-09-2008, 19:50
E' una normalissima classe. La puoi creare anche vuota. :D
Per usarlo basta fare così:
with open('xml.dump') as f:
self.p.ParseFile(f)
;)
Sick Boy
01-10-2008, 08:50
ciao,
ho provato a fare come hai detto tu, mettendo quelle righe di codice in una classe, che chiamo parsing
class parsing:
self.p = xml.parsers.expat.ParserCreate()
self.p.buffer_text = True
self.p.returns_unicode = False
self.p.StartElementHandler = self.start_element
self.p.EndElementHandler = self.end_element
self.p.CharacterDataHandler = self.char_data
però così mi da errore perchè non ho dichiarato self. cosa devo modificare?
a te sembreranno cose ovvie, ma per me che sono agli inizi della programmazione in python non lo sono per niente!
cdimauro
01-10-2008, 08:58
Potevi dirlo prima. :D
Ecco qua:
from __future__ import with_statement
import xml.parsers.expat
class SimpleXMLParser(object):
def __init__(self, FileName):
self.p = xml.parsers.expat.ParserCreate()
self.p.buffer_text = True
self.p.returns_unicode = False
self.p.StartElementHandler = self.start_element
self.p.EndElementHandler = self.end_element
self.p.CharacterDataHandler = self.char_data
with open(FileName) as f:
self.p.ParseFile(f)
def start_element(self, name, attrs):
print 'Ho trovato il tag', name, 'con gli attributi', attrs
def end_element(self, name):
print 'Tag', name, 'chiuso'
def char_data(self, data):
print 'In mezzo al tag ho trovato questi dati:', data
SimpleXMLParser('xml.dump')
;)
Sick Boy
01-10-2008, 09:06
ok!
ho provato a compilare tutto, mettendolo in un file (es parser.py)! mi da questo errore
SyntaxError: Invalid Syntax
e mi segna la riga
with open(FileName) as f:
in particolare "open"
grazie per la pazienza! ;)
cdimauro
01-10-2008, 09:42
Probabilmente c'è qualche problema di indentazione.
Eventualmente riportami il file che hai creato o il traceback dello stack.
P.S. Di nulla. :)
Sick Boy
01-10-2008, 16:03
eccolo qui:
from __future__ import with_statement
import xml.parsers.expat
class SimpleXMLParser(object):
def __init__(self, FileName):
self.p = xml.parsers.expat.ParserCreate()
self.p.buffer_text = True
self.p.returns_unicode = False
self.p.StartElementHandler = self.start_element
self.p.EndElementHandler = self.end_element
self.p.CharacterDataHandler = self.char_data
with open(FileName) as f:
self.p.ParseFile(f)
def start_element(self, name, attrs):
print 'Ho trovato il tag', name, 'con gli attributi', attrs
def end_element(self, name):
print 'Tag', name, 'chiuso'
def char_data(self, data):
print 'In mezzo al tag ho trovato questi dati:', data
SimpleXMLParser('xml.dump')
ah, ma questo codice mi trova il file ovunque si trovi?
cdimauro
02-10-2008, 07:34
eccolo qui:
from __future__ import with_statement
import xml.parsers.expat
class SimpleXMLParser(object):
def __init__(self, FileName):
self.p = xml.parsers.expat.ParserCreate()
self.p.buffer_text = True
self.p.returns_unicode = False
self.p.StartElementHandler = self.start_element
self.p.EndElementHandler = self.end_element
self.p.CharacterDataHandler = self.char_data
with open(FileName) as f:
self.p.ParseFile(f)
def start_element(self, name, attrs):
print 'Ho trovato il tag', name, 'con gli attributi', attrs
def end_element(self, name):
print 'Tag', name, 'chiuso'
def char_data(self, data):
print 'In mezzo al tag ho trovato questi dati:', data
SimpleXMLParser('xml.dump')
Hai sbagliato l'indentazione dell'istruzione with.
Il codice corretto è questo:
from __future__ import with_statement
import xml.parsers.expat
class SimpleXMLParser(object):
def __init__(self, FileName):
self.p = xml.parsers.expat.ParserCreate()
self.p.buffer_text = True
self.p.returns_unicode = False
self.p.StartElementHandler = self.start_element
self.p.EndElementHandler = self.end_element
self.p.CharacterDataHandler = self.char_data
with open(FileName) as f:
self.p.ParseFile(f)
def start_element(self, name, attrs):
print 'Ho trovato il tag', name, 'con gli attributi', attrs
def end_element(self, name):
print 'Tag', name, 'chiuso'
def char_data(self, data):
print 'In mezzo al tag ho trovato questi dati:', data
SimpleXMLParser('xml.dump')
ah, ma questo codice mi trova il file ovunque si trovi?
No, dev'essere nella cartella in cui hai lanciato l'applicazione.
Sick Boy
02-10-2008, 09:01
anche così indentato mi da lo stesso errore!:muro:
cdimauro
02-10-2008, 09:24
Prima di postarlo l'ho provato. Ecco qua (scusa la censura, ma ho ho usato un xml di produzione):
D:\Test>python "Prova XML.py"
Ho trovato il tag PEPCommandList con gli attributi {'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:noNamespaceSchemaLocation': '\\PEPCommand
.xsd'}
In mezzo al tag ho trovato questi dati:
Ho trovato il tag PEPCommand con gli attributi {}
In mezzo al tag ho trovato questi dati:
Ho trovato il tag id_comando con gli attributi {'value': '1383288'}
Tag id_comando chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag id_autorizzazione con gli attributi {'idAuth': '2'}
Tag id_autorizzazione chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag id_csp con gli attributi {'IDValue': '***CENSORED***'}
Tag id_csp chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag op_type con gli attributi {'op_typeValue': 'DISATTIVAZIONE'}
Tag op_type chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag username con gli attributi {'nameValue': '***CENSORED***'}
Tag username chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag type con gli attributi {'typeValue': 'TRIGGER_CLASSICO'}
Tag type chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag canale_in con gli attributi {'chosenInStream': 'SMS'}
Tag canale_in chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag canale_out con gli attributi {'chosenOutStream': 'WAP-PUSH'}
Tag canale_out chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag categoria con gli attributi {'serviceId': '***CENSORED***'}
Tag categoria chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag motivo con gli attributi {'motivoValue': 'Stato Utenza'}
Tag motivo chiuso
In mezzo al tag ho trovato questi dati:
Ho trovato il tag la_mittente con gli attributi {'la_mittenteValue': '12345'}
Tag la_mittente chiuso
In mezzo al tag ho trovato questi dati:
Tag PEPCommand chiuso
In mezzo al tag ho trovato questi dati:
Tag PEPCommandList chiuso
Sick Boy
02-10-2008, 09:33
non riesco a capire il problema che ho.
mi spieghi la linea di codice
from __future__ import with_statement
Sick Boy
02-10-2008, 09:44
ok, ora mi stampa a video le informazioni!
ho cancellato la prima riga di import e ho usato al posto delle due linee in cui apre il file questa unica riga di codice:
self.p.ParseFile(open(FileName))
così funziona! ora devo formattare meglio l'output perchè il dump che ricevo in ingresso è formato da più tag "<?xml.." e infatti dopo il primo elemento di quel file mi da queste linee di errore:
Traceback (most recent call last):
File "parser.py", line 24 in ?
SimpleXMLParser('xml.dump')
File "parser.py", line 13, in __init__
self.p.ParseFile(open(FileName))
xml.parsers.expat.ExpatError: junk after document element: line 66, column 0
e poi c'è la seconda fase:
CREARE UNA FINESTRA CHE MI MOSTRI I VARI TAG PADRE CON ALL'INTERNO I TAG FIGLIO
cdimauro
02-10-2008, 09:55
non riesco a capire il problema che ho.
mi spieghi la linea di codice
from __future__ import with_statement
Ti permette di usare l'istruzione with.
ok, ora mi stampa a video le informazioni!
ho cancellato la prima riga di import e ho usato al posto delle due linee in cui apre il file questa unica riga di codice:
self.p.ParseFile(open(FileName))
così funziona! ora devo formattare meglio l'output.
Di norma dovresti aprire il file e poi chiuderlo.
e poi c'è la seconda fase:
CREARE UNA FINESTRA CHE MI MOSTRI I VARI TAG PADRE CON ALL'INTERNO I TAG FIGLIO
Non mi sono ancora cimentato con le interfacce grafiche con Python, mi spiace.
Sick Boy
02-10-2008, 10:15
e per questo problema? il dump che ha più tag xml cosa faresti?
ora devo formattare meglio l'output perchè il dump che ricevo in ingresso è formato da più tag "<?xml.." e infatti dopo il primo elemento di quel file mi da queste linee di errore:
Traceback (most recent call last):
File "parser.py", line 24 in ?
SimpleXMLParser('xml.dump')
File "parser.py", line 13, in __init__
self.p.ParseFile(open(FileName))
xml.parsers.expat.ExpatError: junk after document element: line 66, column 0
cdimauro
03-10-2008, 07:15
Non mi sembra sia un XML standard. Dovrebbe avere un solo tag <xml
In questo caso dovresti prendere il file, leggerlo in memoria, suddividerlo nelle sezioni xml presenti e parserizzarle una alla volta.
cdimauro, desideravo chiederti una mano a proposito del parser che hai scritto.
Volevo fare il parsing di diversi file di log di msn che ho in formato XML per renderli più leggibili in stile file di log di irc.
Il file XML che viene letto è composto da molte righe di questo tipo:
<Message Date="01/06/2008" Time="13.22.13" DateTime="2008-06-01T11:22:13.296Z" SessionID="1"><From><User FriendlyName="NickNameMittente"/></From><To><User FriendlyName="NickNameDestinatario"/></To><Text Style="font-family:Segoe UI; font-style:italic; color:#0000ff; ">Testo Messaggio</Text></Message>
Ovviamente il tuo parser funziona :D e fornisce un output di questo tipo:
Ho trovato il tag Log con gli attributi {'FirstSessionID': '1', 'Archive': 'true', 'LastSessionID': '18'}
Ho trovato il tag Message con gli attributi {'Date': '01/06/2008', 'SessionID': '1', 'DateTime': '2008-06-01T11:22:13.296Z', 'Time': '13.22.13'}
Ho trovato il tag From con gli attributi {}
Ho trovato il tag User con gli attributi {'FriendlyName': 'NickNameMittente'}
Tag User chiuso
Tag From chiuso
Ho trovato il tag To con gli attributi {}
Ho trovato il tag User con gli attributi {'FriendlyName': 'NickNameDestinatario'}
Tag User chiuso
Tag To chiuso
Ho trovato il tag Text con gli attributi {'Style': 'font-family:Segoe UI; font-style:italic; color:#0000ff; '}
In mezzo al tag ho trovato questi dati: Testo Messaggio
Tag Text chiuso
Tag Message chiuso
Tag Log chiuso
Io vorrei prendere i valori degli attributi Date e Time del tag Message,il valore dell'attributo FriendlyName del tag User racchiuso a sua volta dal tag From,ed il Testo Messaggio racchiuso nel tag Text, quindi creare una stringa così
formata
[Date @ Time] <FriendlyName> Testo Messaggio
Se ho capito e pensato correttamente, dovrei giocare sui tre gestori StartElementHandler,EndElementHandler,CharacterDataHandler per ottenere ciò che voglio, soprattuto credo StartElementHandler.
Le stringhe relative agli attributi dovrei splittarle per prendere ciò che mi interessa ma soprattutto nella funzione
def start_element(self, name, attrs):
è corretto pensare ad una serie di if per costruire la stringa come vorrei?
cdimauro
03-11-2008, 20:55
Sei sulla buona strada. Ti do qualche indicazione (se ci arrivi da solo... l'XML non avrà più limiti per te :D).
Il mio primo suggerimento è quello di intercettare l'inizio del tag Message e inizializzare opportunamente le variabili che conterranno i dati che t'interessano. Ovviamente è meglio utilizzare delle variabili d'istanza allo scopo (basta un self.NomeVariabile e sei a posto).
Per essere precisi, all'inizio di Message ti basterà copiare il valore di Date e Time.
Per FriendlyName non puoi farlo, perché può essere racchiuso dal tag From o da To. Devi quindi memorizzarti il nome del tag "padre", usando sempre un'opportuna variabile d'istanza. Visto che ci possono essere al massimo 2 livelli, ti basta creare un FatherTag e un CurrentTag per memorizzare rispettivamente il tag precedente e quello attuale; non è complicato (è più difficile a dirsi che a farsi): ti bastano un paio di righe di codice all'inizio del tag.
Per Text c'è da fare qualche lavoro in più. All'inizio del tag devi inizializzare la variabile che dovrà contenere il testo con la stringa vuota. Poi nell'handler che scatta quando viene rilevato del testo presente in mezzo al tag, ti basta prendere il valore e appenderlo alla stringa di cui sopra. Alla fine del tag puoi copiarlo nell'apposita variabile d'instanza.
Sembra complicato, ma vedrai che non avrai particolari difficoltà. :p
Comunque se hai delle difficoltà chiedi pure. :)
^TiGeRShArK^
03-11-2008, 20:59
...forse è un pò OT, però da quando ho scoperto LinqToXml manipolare i file XML non è poi così brutto... :stordita:
class Program
{
static void Main(string[] args)
{
XDocument doc = XDocument.Load(@"Z:\Documents\File ricevuti\*******3638208852\Cronologia\***********.xml");
var messages = from m in doc.Descendants("Message")
select String.Format("[{0} {1}] <{2}> {3}",
(string)m.Attribute("Date"),
(string)m.Attribute("Time"),
(string)(m.Element("From").Element("User").Attribute("FriendlyName")),
(string)m.Element("Text"));
messages.ToList().ForEach(Console.WriteLine);
Console.ReadLine();
}
}
Grazie per i suggerimenti, mi metto subito al lavoro.
P.S. ^TiGeRShArK^, è in C# il tuo codice?
^TiGeRShArK^
03-11-2008, 21:19
Grazie per i suggerimenti, mi metto subito al lavoro.
P.S. ^TiGeRShArK^, è in C# il tuo codice?
yes :p
e fa esattamente quello che volevi fare :D
yes :p
e fa esattamente quello che volevi fare :D
Funziona correttamente con C# Express Edition?
Comunque per principio ce la devo fare anche in Python. :D
cdimauro
03-11-2008, 21:21
...forse è un pò OT, però da quando ho scoperto LinqToXml manipolare i file XML non è poi così brutto... :stordita:
class Program
{
static void Main(string[] args)
{
XDocument doc = XDocument.Load(@"Z:\Documents\File ricevuti\*******3638208852\Cronologia\***********.xml");
var messages = from m in doc.Descendants("Message")
select String.Format("[{0} {1}] <{2}> {3}",
(string)m.Attribute("Date"),
(string)m.Attribute("Time"),
(string)(m.Element("From").Element("User").Attribute("FriendlyName")),
(string)m.Element("Text"));
messages.ToList().ForEach(Console.WriteLine);
Console.ReadLine();
}
}
Anche in Python puoi usare ElementTree (http://docs.python.org/library/xml.etree.elementtree.html) per manipolare i nodi dell'XML letto, ma... si deve leggere l'XML, appunto, e costruire l'albero.
Io preferisco expat perché consuma meno memoria e mi permette di selezionare "al volo" i dati che mi servono, ignorando tutti gli altri.
^TiGeRShArK^
04-11-2008, 00:40
Anche in Python puoi usare ElementTree (http://docs.python.org/library/xml.etree.elementtree.html) per manipolare i nodi dell'XML letto, ma... si deve leggere l'XML, appunto, e costruire l'albero.
Io preferisco expat perché consuma meno memoria e mi permette di selezionare "al volo" i dati che mi servono, ignorando tutti gli altri.
mmmmm...
consuma meno memoria...
mmm...
SAX parser? :mbe:
perchè se usa il dom mi sa che siamo lì..
e comunque preferisco consumare + memoria piuttosto che bestemmiare appresso agli XML :D
.Infatti non vedo l'ora che estendano LinqToSql ad altri DB diversi da SQL server :stordita:
me sò 'namorato de linq.. :stordita:
...tutta colpa di gugoxx :fagiano:
^TiGeRShArK^
04-11-2008, 00:43
Funziona correttamente con C# Express Edition?
Comunque per principio ce la devo fare anche in Python. :D
Si, funziona perfettamente..
l'unica cosa è che devi incollare questo codice in una classe statica nel tuo progetto:
public static void ForEach<T>(this IEnumerable<T> domain, Action<T> action)
{
foreach (T elem in domain) action(elem);
}
perchè la funzione ForEach non è standard ma è una Extension :p
mmm..
e ovviamente ti serve il .Net >= 3.0 :D
cdimauro
04-11-2008, 07:08
mmmmm...
consuma meno memoria...
mmm...
SAX parser? :mbe:
perchè se usa il dom mi sa che siamo lì..
No, è abbastanza diversa: http://en.wikipedia.org/wiki/Expat_(XML)
Le callback vengono chiamate man mano che vengono riconosciuti i dati. Quindi l'occupazione di memoria è veramente minimale.
e comunque preferisco consumare + memoria piuttosto che bestemmiare appresso agli XML :D
Sicuramente. :) Infatti quella che ho postato prima è una versione minimale di classe per il parsing con expat, ma nelle mie librerie la classe l'ho "leggermente" potenziata e resa più semplice e flessibile. :D
.Infatti non vedo l'ora che estendano LinqToSql ad altri DB diversi da SQL server :stordita:
me sò 'namorato de linq.. :stordita:
...tutta colpa di gugoxx :fagiano:
:asd: Mi fai venir voglia di implementare LINQ in Python. :fagiano:
^TiGeRShArK^
04-11-2008, 12:17
No, è abbastanza diversa: http://en.wikipedia.org/wiki/Expat_(XML)
trovato:
Expat's parsing events are similar to the events defined in the Simple API for XML (SAX), but Expat is not a SAX-compliant parser.
ecco perchè mi ricordava sax :D
Vincenzo1968
04-11-2008, 15:16
Se l'obiettivo è quello di risparmiare memoria, l'unica soluzione è quella di implementare a mano il proprio parser, utilizzando un automa a stati finiti di tipo deterministico(si guadagna anche in velocità di esecuzione).
;)
^TiGeRShArK^
04-11-2008, 16:22
Se l'obiettivo è quello di risparmiare memoria, l'unica soluzione è quella di implementare a mano il proprio parser, utilizzando un automa a stati finiti di tipo deterministico(si guadagna anche in velocità di esecuzione).
;)
mi sa che in questo caso la priorità è risparmiarsi lo sbattimento di parsare l'xml con metodi immondi dato che con 8 righe di codice risolvi correttamente il problema...e i log di msn non mi pare siano tanto mission critical da richiedere le migliori prestazioni possibili :D
Beh, credo che il discorso di Vincenzo sia generico. :D
^TiGeRShArK^ il tuo codice funziona senza quella classe statica che hai incollato successivamente.
Vincenzo1968
04-11-2008, 16:45
mi sa che in questo caso la priorità è risparmiarsi lo sbattimento di parsare l'xml con metodi immondi dato che con 8 righe di codice risolvi correttamente il problema...e i log di msn non mi pare siano tanto mission critical da richiedere le migliori prestazioni possibili :D
S'era parlato di risparmio di memoria. Se l'obiettivo è quello di sparagnare al massimo la memoria utilizzata dal programma, è follia pura utilizzare LinkToXml o qualche altra libreria preconfezionata.
Implementare un automa è semplicissimo, qualunque sia il linguaggio adottato. Il prezzo da pagare è la scrittura di qualche riga di codice in più.
;)
^TiGeRShArK^
04-11-2008, 16:53
Beh, credo che il discorso di Vincenzo sia generico. :D
^TiGeRShArK^ il tuo codice funziona senza quella classe statica che hai incollato successivamente.
ah già il ForEach sulle liste è già implementato e io avevo convertito l'IEnumerable in Lista senza rendermene conto :stordita:
^TiGeRShArK^
04-11-2008, 16:56
S'era parlato di risparmio di memoria. Se l'obiettivo è quello di sparagnare al massimo la memoria utilizzata dal programma, è follia pura utilizzare LinkToXml o qualche altra libreria preconfezionata.
Implementare un automa è semplicissimo, qualunque sia il linguaggio adottato. Il prezzo da pagare è la scrittura di qualche riga di codice in più.
;)
beh.. oddio..
dipende da cosa intendi per "qualche" :D
così ad occhio il numero di righe di codice per implementare l'automa a stati finiti e ottenere lo stesso risultato aumenterebbe di almeno 10-15 volte :mbe:
sarebbe un pò come ammazzare una mosca con una bomba H :fagiano:
Vincenzo1968
04-11-2008, 17:09
beh.. oddio..
dipende da cosa intendi per "qualche" :D
così ad occhio il numero di righe di codice per implementare l'automa a stati finiti e ottenere lo stesso risultato aumenterebbe di almeno 10-15 volte :mbe:
sarebbe un pò come ammazzare una mosca con una bomba H :fagiano:
A me non spaventa l'idea di scrivere del codice. Sarà anche per via del fatto che trovo affascinante l'argomento parsing. Parlo in generale; sono per esempio affascinato dal funzionamento di un compilatore. Mi piace sapere come funziona, come riesce a leggere un codice sorgente e convertirlo in un programma funzionante.
Nel caso particolare proposto da Xfree, penso che l'automa sia la soluzione ideale, visto che non si tratta di effettuare il parsing di un XML con decine o centinaia di livelli di annidamento per i nodi figli.
A proposito, XFree, vorrei, quando ho qualche minuto, implementarne uno di automa per il tuo problema. Ti chiedo, in output, per l'attributo <FriendlyName>, quale ti serve? Quello all'interno del tag <From> o quello all'interno del tag <To>?
O.T.:
P.S. Tiger, vedi che, come ti dicevo nell'altra sezione del forum, in questa, di sezione, ci 'scontriamo'? Politicamente abbiamo idee affini ma divergenti, invece, nel campo della programmazione :D
^TiGeRShArK^
04-11-2008, 17:13
A me non spaventa l'idea di scrivere del codice. Sarà anche per via del fatto che trovo affascinante l'argomento parsing. Parlo in generale; sono per esempio affascinato dal funzionamento di un compilatore. Mi piace sapere come funziona, come riesce a leggere un codice sorgente e convertirlo in un programma funzionante.
Nel caso particolare proposto da Xfree, penso che l'automa sia la soluzione ideale, visto che non si tratta di effettuare il parsing di un XML con decine o centinaia di livelli di annidamento per i nodi figli.
A proposito, XFree, vorrei, quando ho qualche minuto, implementarne uno di automa per il tuo problema. Ti chiedo, in output, per il campo <FriendlyName>, cosa ti serve? Quello all'interno del tag <From> o quello all'interno del tag <To>?
O.T.:
P.S. Tiger, vedi che, come ti dicevo nell'altra sezione del forum, in questa, di sezione, ci 'scontriamo'? Politicamente abbiamo idee affini ma divergenti, invece, nel campo della programmazione :D
sarà perchè a me piace scrivere nel minor tempo possibile il codice + elegante che risolva un problema, mentre a te piace scrivere codice per risolvere il problema nel minor tempo possibile :p
comunque x il campo friendlyname serve quello dentro from :p
Vincenzo1968
04-11-2008, 17:23
sarà perchè a me piace scrivere nel minor tempo possibile il codice + elegante che risolva un problema, mentre a te piace scrivere codice per risolvere il problema nel minor tempo possibile :p
comunque x il campo friendlyname serve quello dentro from :p
Grazie ;)
XFree l'aveva pure specificato nel suo post; disattenzione mia :doh:
:)
cdimauro
05-11-2008, 20:45
Se l'obiettivo è quello di risparmiare memoria, l'unica soluzione è quella di implementare a mano il proprio parser, utilizzando un automa a stati finiti di tipo deterministico(si guadagna anche in velocità di esecuzione).
;)
Col mio esempio servono soltanto DUE variabili per contenere il tag precedente e quello attuale, e due istruzioni per aggiornarle: mi sembra LEGGERMENTE più semplice che andare a impelagarsi con un automa a stati finiti.
Vincenzo1968
05-11-2008, 20:54
Col mio esempio servono soltanto DUE variabili per contenere il tag precedente e quello attuale, e due istruzioni per aggiornarle: mi sembra LEGGERMENTE più semplice che andare a impelagarsi con un automa a stati finiti.
No, dicevo, è follia pura non impelagarsi con l'automa se l'obiettivo è quello di massimizzare il risparmio di memoria.
;)
cdimauro
05-11-2008, 22:30
E' follia pura utilizzare un automa quando bastano DUE variabili per risolvere il problema.
Ciao a tutti!
Mi sto maledettamente impelagando per parserizzare vari file xml e usando SAX (aventi tutti la stessa struttura).
Il mio problema è il seguente: tramite una listbox seleziono i file xml che voglio parserizzare. Una volta selezionati, premo un pulsante che mi costruisce una tabella con i dati contenuti NEL PRIMO FILE scelto. Procedo così, perchè diciamo che questi dati sono uguali per tutti i file, quindi risparmio delle parserizzazioni inutili e poichè la tabella è modificabile, evito di sovrascrivere nuovamente i dati inseriti dall'utente.
Il mio problema è che, oltre a questi dati comuni, ci sono 3 tag che cambiano da file a file e di cui mi serve conservare il valore poichè poi premendo un altro bottone opero proprio su questi dati "nuovi" in aggiunta a quelli "comuni".
Come mi conviene strutturare la classe del parser e quella che richiama il parser per ogni file?
Grazie mille!
Dimenticavo il codice che ho usato finora:
from xml.sax import make_parser
from xml.sax.handler import ContentHandler
parser=make_parser()
handler=TagInfoHandler(self.rifWx)
parser.setContentHandler(handler)
for filexml in listbox parser.parse(filexml)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.