Newsgroup: it.comp.lang.visual-basic
Titolo: Parser XML e tag sparsi - Come lo faccio?

Salve a tutti,
Innanzitutto premetto che sto usando il .net framework 2.0.
Devo parsare un testo del genere:
[COLOR=darkred][B]testoUno[/B][/COLOR]
[B][COLOR=green]testoDue[/COLOR]testoTre[/B]
Ogni "blocco" di questo genere è praticamente un record.
Inizia con il COLOR etc. e finisce con l'ultimo /B.
Ora il problema è, come faccio a scorrere questo testo e via via inserire 
query in un db estrapolando i dati da questo?
Io innanzitutto pensavo di trasformare le quadre in parentesi classiche dei 
tag XML:
<COLOR=darkred><B>testoUno</B></COLOR>
<B><COLOR=green>testoDue</COLOR>testoTre</B>
Una volta fatto ciò, però, come faccio per ricavarmi i vari "testoUno", 
"testoDue" e "testoTre"?
Per ora ho fatto qualcosa del genere ma i tag erano ordinati e uno dentro 
l'altro del tipo:
<tagContenitore>
    <tagUno>testoUno</tagUno>
    <tagDue>testoDue</tagDue>
    <tagTre>testoTre</tagTre>
</tagContenitore>
Come faccio invece per i tag che servono a me? Sono "sparsi" e non saprei da 
dove cominciare...
Come mi consigliate di fare?
Qual'è il modo più "pulito" e semplice di fare ciò?
Grazie a tutti in anticipo,
-- 
Carmine
Webmaster di 
www.thetotalsite.it
Blog 
http://blog.thetotalsite.it
 

 [B][COLOR=green]testoDue[/COLOR]testoTre[/B]
Aggiungo che inoltre a volte potrebbe diventare ciň roba tipo:
[COLOR=darkred][B]testoUno[/B][/COLOR]
[B][COLOR=green]testoDue[/COLOR]testoTre
[COLOR=green]testoQuattro[/COLOR]testoCinque[/B]
Praticamente il secondo B in questo caso sarebbe il contenitore.
Il testo di testoDue/testoTre/testoQuattro/testoCinque non mi serve 
"differenziato"; ma va benissimo anche concatenato.
Come fare quindi?


 Bloghttp://
blog.thetotalsite.it
presupponendo che tu abbia un file XML valido.....
Imports System.Data
...ho un file chiamato citazioniXML (me lo son fatto generare da
access....con la funzione Esporta in formato XML)
un bottone su una form
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button3.Click
        Dim mDS As New DataSet
        mDS.ReadXml("CitazioniXML.xml")
End Sub
Voilà....nel dataset c'è una tabella citazioni!

È qui il problema.
Il file XML non è autogenerato o altro, bensì sarebbe il BB code di un 
forum.
Aggiungo un esempio:
Mettiamo caso che questo file sia un archivio di barzellette; testoUno è il
titolo della barzelletta, testoDue è il testo della barzelletta, testoTre è
l'autore della barzelletta.
Ora io vorrei ricavare questi tre valori in modo da inserirli in una tabella
di database del tipo:
NomeBarzelletta | TestoBarzelletta | AutoreBarzelletta
Il problema è che a volte può capitare che ci siano più "testi" barzelletta
scritti da diversi autori, per cui avrò:
testoUno = titolo barzelletta
testoDue = testo barzelletta
testoTre = autore barzelletta
testoQuattro = secondo testo barzelletta
testoCinque = secondo autore barzelletta
e via dicendo.
Il file che devo parsare è strutturato, ad esempio, così:
[COLOR=darkred][B]testoUno[/B][/COLOR]
[B][COLOR=green]testoDue[/COLOR]testoTre[/B]
[COLOR=darkred][B]testoUno[/B][/COLOR]
[B][COLOR=green]testoDue[/COLOR]testoTre
[COLOR=green]testoQuattro[/COLOR]testoCinque[/B]
[COLOR=darkred][B]testoUno[/B][/COLOR]
[B][COLOR=green]testoDue[/COLOR]testoTre[/B]
[COLOR=darkred][B]testoUno[/B][/COLOR]
[B][COLOR=green]testoDue[/COLOR]testoTre[/B]
E ogni "blocco" che inizia con [COLOR=darkred] e finisce con [/B] è una
barzelletta da inserire come riga nella tabella di database.
Il problema è appunto, come faccio a ricavare i valori da questo file?
Il fatto è che non posso nemmeno separare i vari record contando il "a capo"
come fosse il segno di distinzione tra dove inizia un record e finisce
quello precedente; in quanto può capitare che il testo della barzelletta sia
esso stesso su più righe, e se facessi così mi "spezzerebbe" il record e non
funzionerebbe più nulla:
[COLOR=darkred][B]testoUno[/B][/COLOR]
[B][COLOR=green]testo
                                         <--- in questo caso lo conterebbe
come se fosse una nuova barzelletta, ma in realtà è sempre la stessa.
Due[/COLOR]testoTre[/B]
Ciao,


 forum.
zac
Beh se provando a sostuire è [ con < come hai detto non succede nulla
(prova non si sà mai)....
"Parserizza" (bruttissima traduzione....analizza...esamina...traduci)
il file con i classici comandi!
VB.net....ha la funzione MID come il vb6...anzi parecchio più
potente....
e oltre alle solite di ricerca e sostituzione (molto potenziate)
ad esempio
... ha anche .lastIndexofAny come metodo di una variabile stringa!
se cerchi sull'help
 Metodo String.LastIndexOfAny (Char[], Int32)
l'help ti riporta un codice di esempio che cerca una occorenza in una
stringa....

Mhm stavo un po' vedendo...
(comunque, sostituendo le [ con gli < non lo prende comunque il readxml).
Il problema č che, i comandi come LastIndexOf, Mid etc; riescono a lavorare 
su stringhe di roba tipo 10.000 caratteri o diventano lentissime? Si tratta 
piů o meno di 3-4 pagine A4 di testo per dare un idea.
E poi, dove potrei trovare un esempio di questo LastIndexOfAny?
Cosa cambia tra LastIndexOf e LastIndexOfAny?
A quanto ho capito mi restituiscono l'indice del primo carattere trovato; e 
dopo con substring posso estrarre il tutto.
Ma poi come faccio a "scorrere" la selezione?


RISOLTO!
Ho risolto modificando leggermente il codice in "entrata" e ricavando una 
collection di classi con i vari record:
Private Function GetBarzelletteFromXElement(ByVal root As XElement) As
IList(Of Barzelletta)
        Dim barzellette As New List(Of Barzelletta)
        Dim barzelletta As New Barzelletta
        For Each element As XElement In root.Descendants
            If element.Name = "span" Then
                Dim color As String =
element.Attributes("color").First.Value
                If (color = "darkred") Then
                    barzelletta = New Barzelletta()
                    barzelletta.Title = element.Descendants.First.Value
                    barzellette.Add(barzelletta)
                ElseIf color = "green" Then
                    barzelletta.Paraghraps.Add(element.Value)
                ElseIf color = "author" Then
                    If Not element.Value = "" Then
                        barzelletta.Author.Add(element.Value)
                    End If
                End If
        Next
        Return barzellette
    End Function
Per il resto del codice e chiarimenti vari vedere il thread omonimo su 
microsoft.public.it.dotnet.vb
Bye,
