Italian Lettura / Scrittura Valore su XML

Xfood

Expert
Licensed User
Buongiorno a Tutti,
ho la necessita di modificare a runtime un file XML,
leggo il file, se trovo un certo valore vorrei poi modificarlo, e quindi salvare nuovamente il file.xml,
ho questo codice di esempio, con cui riesco a leggere i valori, ma non so come sostituirli
qualche idea?

B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private XMLParser As SaxParser
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    XMLParser.Initialize
    ParseSoapResult
    MainForm.Close
End Sub
'
Sub ParseSoapResult
    Dim soapresult As String = File.ReadString(File.DirApp, "rep_kala2.jrxml")
    XMLParser.parse(StringToInputStream (soapresult), "Parser")
End Sub

Sub Parser_EndElement (Uri As String, Name As String, Text As StringBuilder)
    
    Log("-------------   Lettura   *******")
    Log(Uri& " Uri")
    Log(Name & " Name")
    Log(Text.ToString & " text")
    
    Select Name
        Case "queryString"
          [B]  ' qui vorrei sostituire il valore[/B]
        Case "text"
            If Text.ToString="@@Variabile1" Then
              [B]  'qui vorrei sostituire il valore[/B]
            End If
            
    
    End Select
End Sub


Sub StringToInputStream (s As String) As InputStream
   Dim In As InputStream
   Dim data() As Byte = s.GetBytes("UTF8")
   In.InitializeFromBytesArray(data, 0, data.Length)
   Return In
End Sub
 

Xfood

Expert
Licensed User
bene ragazzi,
non ho trovato il modo di "scrivere" una chiave su un xml, leggerela e fare il parser si,
vedi esempio di prova,
comunque il mio scopo era trovare delle " chiavi " civetta dentro il file " Template",
sostituirle con dei valore, e creare un nuovo file
a tal proposito ho utilizzato una cosa semplice
eccola
B4X:
Dim NewFile As List
    NewFile.Initialize
   
    For Each line As String In File.ReadList(File.DirApp, "ReportTemplate.jrxml")
        Log(line)
        If line.Contains("@@Variabile1")=True Then
            line=line.Replace("@@Variabile1","Valore_Calcolato")
        End If
        If line.Contains("@@Variabile2")=True Then
            line=line.Replace("@@Variabile2","qta*prezzo")
        End If
        If line.Contains("SELECT * from Articoli")=True Then
            line=line.Replace("SELECT * from Articoli","SELECT * from Articoli where id >3")
        End If
       '' If line.Contains(ecc....)=True Then
            'line=line.replace("ecc...","con quelloo che vuoi")
       '' End If
       NewFile.Add(line)
     
    Next
   
    File.Writelist(File.DirApp, "Report.jrxml",NewFile)
 

Xfood

Expert
Licensed User
Riprendo questo post,
anche se avevo trovato una soluzione di comodo,
adesso ho la necessita' di leggere un valore su un file xml ( usato come configuratore / parametri)
e anche scrivere o sostituire dei valori che a priori non conosco,
quindi cercando in lungo e in largo non ho trovato una cosa semplice per leggere un valore e per scrivere una valore su una chiave,
un po come si fa con i file ini,
per cui ho creato 2 funzioncine ( magari servono a qualcuno)
che per adesso risolvono almeno in parte la mia esigenza
sicuramente esiste un modo piu elegante di leggere e scrivere un xml
se qualcuno ha un modo migliore piu professionale, lo adotterei volentieri.
intanto ecco la mia piccola funzioncina
allego anche il file xml

B4X:
    Dim xml As String
    xml=File.ReadString("c:\syspc\tabelle\1\","cassa_1.xml")
   
   
    ' per leggere un valore
    Dim valore As String =TrovaValoreXml("IpAddress",xml)
    Log(valore)


' per scrivere dei valori nel file xml
    xml=ScriviValoreXml("NumeroTerminale","1",xml)
    xml=ScriviValoreXml("IpAddress","192.168.1.109",xml)
    xml=ScriviValoreXml("NomeDiRete","192.168.1.109",xml)
   
    File.WriteString("c:\syspc\tabelle\1\","cassa_1.xml",xml)

Private Sub TrovaValoreXml(chiave As String,Testoxml As String) As String
    Dim start,stop,ValoreRitorno As String
    Dim StartId,Stopid As Int
    ValoreRitorno=""
   
    start = "<" & chiave & ">"
    stop = "</" & chiave & ">"
    Log(Testoxml)

    StartId= Testoxml.IndexOf(start)
    Stopid = Testoxml.IndexOf(stop)
    'Log(StartId)
    'Log(Stopid)
    If StartId> -1 And Stopid >-1 Then
       
    ValoreRitorno = Testoxml.substring2(StartId+start.Length ,Stopid)
    'Log (ValoreRitorno)
   End If
    Return ValoreRitorno
End Sub

Private Sub ScriviValoreXml(chiave As String,Valore As String, TestoXml As String) As String
    Dim start,stop,ValoreRitorno As String
    Dim StartId,Stopid As Int
    ValoreRitorno=""
   
    start = "<" & chiave & ">"
    stop = "</" & chiave & ">"
   

    StartId= TestoXml.IndexOf(start)
    Stopid = TestoXml.IndexOf(stop)
    'Log(StartId)
    'Log(Stopid)
    If StartId> -1 And Stopid >-1 Then
       
        ValoreRitorno = TestoXml.substring2(StartId+start.Length ,Stopid)
        ValoreRitorno =  TestoXml.Replace(start & ValoreRitorno & stop,start & Valore & stop)
   End If
    Return ValoreRitorno
End Sub
 

Attachments

  • Cassa_1.XML
    1.9 KB · Views: 97
Last edited:

sirjo66

Well-Known Member
Licensed User
Longtime User
la funzione TrovaValoreXml potevi scriverla in UNA SOLA riga semplicemente utilizzando il RegEx
 

Xfood

Expert
Licensed User
la funzione TrovaValoreXml potevi scriverla in UNA SOLA riga semplicemente utilizzando il RegEx
Ottimo, se metti qui il pezzeto di codice necessario, posso usarlo come spunto, e anche qualche altro potrebbe usufruirne.
Non sono molto pratico con RegEx
 

sirjo66

Well-Known Member
Licensed User
Longtime User
prova questo
B4X:
Private Sub TrovaValoreXml(chiave As String,Testoxml As String) As String
    Dim reg As Matcher = Regex.Matcher("<" & chiave & ">(.*?)<\/" & chiave & ">", Testoxml)
    If reg.Find Then Return reg.Group(1) Else Return "<NOT FOUND>"
End Sub

P.S.: quando ho scritto in UNA SOLA riga stavo ragionando in VB.NET, in B4A servono 2 righe
 

Xfood

Expert
Licensed User
prova questo
B4X:
Private Sub TrovaValoreXml(chiave As String,Testoxml As String) As String
    Dim reg As Matcher = Regex.Matcher("<" & chiave & ">(.*?)<\/" & chiave & ">", Testoxml)
    If reg.Find Then Return reg.Group(1) Else Return "<NOT FOUND>"
End Sub

P.S.: quando ho scritto in UNA SOLA riga stavo ragionando in VB.NET, in B4A servono 2 righe
E sempre molto piu professionale della mia funzione, complimenti.
 

sirjo66

Well-Known Member
Licensed User
Longtime User
se la funzione non trova nulla ritorna "<NOT FOUND>" ma ovviamente puoi cambiarlo come vuoi
 

sirjo66

Well-Known Member
Licensed User
Longtime User
ed eccoti qui l'altra routine
B4X:
Private Sub ScriviValoreXml(chiave As String,Valore As String, TestoXml As String) As String
    Return Regex.Replace("<" & chiave & ">(.*?)<\/" & chiave & ">", TestoXml, "<" & chiave & ">" & Valore & "<\/" & chiave & ">")
End Sub
 

Xfood

Expert
Licensed User
Buongiorno,
Finalmente ho quasi finito la mia utility "Configuratore", adesso mi trovo alle prese con un file txt da cui devo leggere o scrivere un determinato parametro, il problema che la chiave questa volta e' cosi ( ambigua) e cioe:
File txt:
10 valorex
113 valore1
33 valore33
13 xx13
114 valore 114
14 valore 14
Ecc.
Se io volessi leggere ho sostituire il valore del ( tag) 13 come faccio, perche spesso mi trova il valore del 113
Io vorrei per esempio una funzione tipo
Leggitxt(chiave)
Log(leggitxt(13)) dovrebbe rispondere xx13
Invece che valore1 che e' il tag 113
Stessa cosa su scrivitxt( chiave,valore)
Qualche idea?
@sirjo66 fara' un miracolo con Regex???
 

LucaMs

Expert
Licensed User
Longtime User
Buongiorno,
Finalmente ho quasi finito la mia utility "Configuratore", adesso mi trovo alle prese con un file txt da cui devo leggere o scrivere un determinato parametro, il problema che la chiave questa volta e' cosi ( ambigua) e cioe:
File txt:
10 valorex
113 valore1
33 valore33
13 xx13
114 valore 114
14 valore 14
Ecc.
Se io volessi leggere ho sostituire il valore del ( tag) 13 come faccio, perche spesso mi trova il valore del 113
Io vorrei per esempio una funzione tipo
Leggitxt(chiave)
Log(leggitxt(13)) dovrebbe rispondere xx13
Invece che valore1 che e' il tag 113
Stessa cosa su scrivitxt( chiave,valore)
Qualche idea?
@sirjo66 fara' un miracolo con Regex???
Perché non usi una Map?
(meglio ancora sarebbe KeyValueStore2)
 

Xfood

Expert
Licensed User
Perché non usi una Map?
(meglio ancora sarebbe KeyValueStore2)
Il file txt esiste gia, devo leggere ed eventualmente scrivere un certo valore facendo riferimento alla chiave,
Esiste una funzione readmap( file.txt) ?
 

Xfood

Expert
Licensed User
Buongiorno,
Finalmente ho quasi finito la mia utility "Configuratore", adesso mi trovo alle prese con un file txt da cui devo leggere o scrivere un determinato parametro, il problema che la chiave questa volta e' cosi ( ambigua) e cioe:
File txt:
10 valorex
113 valore1
33 valore33
13 xx13
114 valore 114
14 valore 14
Ecc.
Se io volessi leggere ho sostituire il valore del ( tag) 13 come faccio, perche spesso mi trova il valore del 113
Io vorrei per esempio una funzione tipo
Leggitxt(chiave)
Log(leggitxt(13)) dovrebbe rispondere xx13
Invece che valore1 che e' il tag 113
Stessa cosa su scrivitxt( chiave,valore)
Qualche idea?
@sirjo66 fara' un miracolo con Regex???
Buongiorno,
sfruttando la funzione di @sirjo66 sono riuscito nel mio intendo
ecco qua:


B4X:
' esempio di lettura e scrittura'
    Dim TxtParametri As String
    Dim percorso As String="c:\Parametri\"
    Dim Ritorno_a_Capo As String = Chr(13) & Chr(10)
    TxtParametri=File.ReadString(percorso,"Parametri.txt")
    Dim valore As String =LeggiStrtran(Ritorno_a_Capo & "13",Ritorno_a_Capo,TxtParametri)
    Log(valore)
    Dim valore As String =LeggiStrtran(Ritorno_a_Capo & "14",Ritorno_a_Capo,TxtParametri)
    Log(valore)
    TxtParametri=ScriviStrtran(Ritorno_a_Capo & "14",Ritorno_a_Capo," 999" ,TxtParametri)
    File.WriteString(percorso,"Parametri.txt",TxtParametri)


Private Sub ScriviStrtran(xStart As String,xStop As String,Valore As String, Testo As String) As String
    Return Regex.Replace(xStart & "(.*?)" & xStop, Testo, xStart & Valore & xStop )
End Sub

Private Sub LeggiStrtran(xStart As String,xStop As String ,Testo As String) As String
    Dim reg As Matcher = Regex.Matcher(xStart & "(.*?)" & xStop, Testo)
    If reg.Find Then Return reg.Group(1) Else Return "<NOT FOUND>"
End Sub
 

sirjo66

Well-Known Member
Licensed User
Longtime User
B4X:
Private Sub LeggiTxt(Chiave As String, Testo As String) As String
    Dim reg As Matcher = Regex.Matcher2("^" & Chiave & "\s(.*?)$", Regex.MULTILINE, Testo)
    If reg.Find Then Return reg.Group(1) Else Return "<NOT FOUND>"
End Sub

Private Sub ScriviTxt(Chiave As String, Valore As String, Testo As String) As String
    Return Regex.Replace2("^" & Chiave & "\s(.*?)$", Regex.MULTILINE, Testo, Chiave & " " & Valore)
End Sub
 
Last edited:

sirjo66

Well-Known Member
Licensed User
Longtime User
Buongiorno,
sfruttando la funzione di @sirjo66 sono riuscito nel mio intendo
ecco qua:


B4X:
' esempio di lettura e scrittura'
    Dim TxtParametri As String
    Dim percorso As String="c:\Parametri\"
    Dim Ritorno_a_Capo As String = Chr(13) & Chr(10)
    TxtParametri=File.ReadString(percorso,"Parametri.txt")
    Dim valore As String =LeggiStrtran(Ritorno_a_Capo & "13",Ritorno_a_Capo,TxtParametri)
    Log(valore)
    Dim valore As String =LeggiStrtran(Ritorno_a_Capo & "14",Ritorno_a_Capo,TxtParametri)
    Log(valore)
    TxtParametri=ScriviStrtran(Ritorno_a_Capo & "14",Ritorno_a_Capo," 999" ,TxtParametri)
    File.WriteString(percorso,"Parametri.txt",TxtParametri)


Private Sub ScriviStrtran(xStart As String,xStop As String,Valore As String, Testo As String) As String
    Return Regex.Replace(xStart & "(.*?)" & xStop, Testo, xStart & Valore & xStop )
End Sub

Private Sub LeggiStrtran(xStart As String,xStop As String ,Testo As String) As String
    Dim reg As Matcher = Regex.Matcher(xStart & "(.*?)" & xStop, Testo)
    If reg.Find Then Return reg.Group(1) Else Return "<NOT FOUND>"
End Sub
Bravo che ti sei dato da fare, ma hai provato a leggere il primo parametro (cioè il 10) ??
Secondo me con la tua routine non funziona
 

Xfood

Expert
Licensed User
B4X:
Private Sub LeggiTxt(Chiave As String, Testo As String) As String
    Dim reg As Matcher = Regex.Matcher2("^" & Chiave & "\s(.*?)$", Regex.MULTILINE, Testo)
    If reg.Find Then Return reg.Group(1) Else Return "<NOT FOUND>"
End Sub
Fantastico, Funziona Alla Grande...
adesso manca solo la funzione per scrivere.... :)
 
Top