Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - modificare file XML
Forum - C# / VB.NET - modificare file XML - Pagina 2

Pagine: [ 1 2 3 ] Precedente | Prossimo
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 23:05
Sabato, 26/06/2021
Non ho mai imparato ad usare XmlDocuments o HtmlDocuments, perché ogni volta che ho iniziato, poi avevo delle incompatibilità, XML troppo vecchi o troppo nuovi, oppure dialetti dedicati... Se nessuno ci illumina con un esempio, partendo dal tuo Xml, un grazie anticipato :rotfl:

Però non mi sono mai scoraggiato, un Xml è un file testo e trattandolo come tale si possono fare tutte le operazioni pensabili.
Ho scritto due righe. Su un nuovo progetto winform aggiungi un bottone ed una textbox:

Codice sorgente - presumibilmente VB.NET

  1. Imports System.IO
  2.  
  3. Public Class Form1
  4.     Dim XML As String
  5.     Dim pos1 As Integer
  6.     Dim pos2 As Integer
  7.     Dim NodoOUT As String
  8.  
  9.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  10.         TextBox1.Multiline = True
  11.         TextBox1.WordWrap = False
  12.         XML = File.ReadAllText("XUSB.XML")
  13.         Dim NodoIN As String = "<HeadOffsetRegisters>"
  14.         NodoOUT = "</HeadOffsetRegisters>"
  15.         pos1 = XML.IndexOf(NodoIN)
  16.         pos2 = XML.IndexOf(NodoOUT)
  17.         TextBox1.Text = XML.Substring(pos1, pos2 - pos1 + NodoOUT.Length)
  18.     End Sub
  19.  
  20.     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  21.         Dim XMLout As String = XML.Substring(0, pos1)
  22.         XMLout += TextBox1.Text
  23.         XMLout += XML.Substring(pos2 + NodoOUT.Length)
  24.         File.WriteAllText("XUSBmod.XML", XMLout)
  25.     End Sub
  26. End Class



Il programma apre il file: XUSB.XML, che deve esistere nella stessa cartella dell'eseguibile.
Individua i nodi e ne mostra il contenuto, ora nella textbox puoi modificare quello che vuoi, anche aggiungere o togliere una riga PletteRemap.
Cliccando il Button, un nuovo file viene salvato di nome: XUSBmod.XML, sempre nella cartella che contiene l'eseguibile.

Partendo da questo esempio, puoi ampliarlo per ottenere una serie di textbox dove modificare i valori, magari controllando anche la validità dell'input, automatizzare prendendo i valori da dove vuoi, aggiungere una ShowOpen e una ShowSave ecc ecc.

Credo che se anche sapessi padroneggiare XmlDocuments e XmlNode, per una modifica così semplice non li userei.

Ultima modifica effettuata da Carlo il 26/06/2021 alle 23:15


in programmazione tutto è permesso
PM Quote
Avatar
bernie (Normal User)
Pro


Messaggi: 164
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 10:44
Domenica, 27/06/2021
Ciao Carlo
Grazie per l'esempio che funziona modificando i dati dalla textbox.
Come avevi intuito io devo modificare i dati in automatico , e non manualmente .
Avevo quindi pensato una soluzione del genere , ma mi da un errore e non capisco perchè.

Ho prima provato il tuo esempio per vedere se il file modificato era riconosciuto e fino qui tutto ok .
Ho poi pensato di modificare i vari campi che devo modificare, e forse qui mi sono complicato la vita , ma mi sembra la soluzione più logica. Ho caricato la parte del file che veniva visualizzato nella textbox in una variabile stringa( testo1), ho poi creato un xml e l'ho popolato con testo1. A questo punto ho cercato di modificare i vari nodi , ma mi compare l'errore qui di sotto . Evidenziata la riga riportata

System.NullReferenceException: 'Riferimento a un oggetto non impostato su un'istanza di oggetto.'
Dim xmlElem As Xml.XmlNodeList = xmlFile.ChildNodes(1).ChildNodes

Allego la parte di listato che ho modificato .
Codice sorgente - presumibilmente VB.NET

  1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  2.  
  3.         Dim XMLout As String = XML.Substring(0, pos1)
  4.         Dim testo1 As String
  5.         Dim xmlFile As New Xml.XmlDocument()
  6.  
  7.  
  8.         testo1 = XML.Substring(pos1, pos2 - pos1 + NodoOUT.Length)
  9.  
  10.         xmlFile.LoadXml(testo1)
  11.  
  12.         Dim xmlElem As Xml.XmlNodeList = xmlFile.ChildNodes(1).ChildNodes
  13.  
  14.         xmlElem.Item(0).InnerText = "0"
  15.         xmlElem.Item(1).InnerText = "9"
  16.         xmlElem.Item(2).InnerText = "8"
  17.         xmlElem.Item(3).InnerText = "7"
  18.         xmlElem.Item(4).InnerText = "6"
  19.         xmlElem.Item(5).InnerText = "5"
  20.         xmlElem.Item(6).InnerText = "4"
  21.         xmlElem.Item(7).InnerText = "3"
  22.         XMLout += (xmlFile.InnerXml)
  23.         XMLout += XML.Substring(pos2 + NodoOUT.Length)
  24.         File.WriteAllText("C:\DigitalFrame\XUSB2.XML", XMLout)
  25.     End Sub


Grazie

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 22:27
Domenica, 27/06/2021
Come ti avevo detto, non ho dimestichezza con le istruzioni dedicate, perchè, se si padroneggia la manipolazione delle stringhe le istruzioni dedicate sono inutili per compiti semplici, il discorso cambia con HTML o XML complessi, ma ad oggi non ne ho mai sentito la necessità.

Restando nell'ambito della manipolazione delle stringhe hai due possibilità, una adatta se il nodo ha un'impostazione fissa, cioè il valore da cambiare si trova sempre nella stessa posizione nel nodo, la seconda è andare a caccia della posizione del valore da cambiare con IndexOf, usando lo stesso metodo che ho usato per trovare: HeadOffsetRegisters.

Nel primo esempio ti mostro come fare presumendo che i valori da cambiare si trovino sempre nella stessa posizione nel nodo, ho aggiunto tre buttons che simulano l'automazione:
Codice sorgente - presumibilmente VB.NET

  1. Imports System.IO
  2.  
  3. Public Class Form1
  4.     Dim XML As String
  5.     Dim pos1 As Integer
  6.     Dim pos2 As Integer
  7.     Dim NodoOUT As String
  8.  
  9.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  10.         TextBox1.Multiline = True
  11.         TextBox1.WordWrap = False
  12.         XML = File.ReadAllText("XUSB.XML")
  13.         Dim NodoIN As String = "<HeadOffsetRegisters>"
  14.         NodoOUT = "</HeadOffsetRegisters>"
  15.         pos1 = XML.IndexOf(NodoIN)
  16.         pos2 = XML.IndexOf(NodoOUT)
  17.         TextBox1.Text = XML.Substring(pos1, pos2 - pos1 + NodoOUT.Length)
  18.     End Sub
  19.  
  20.     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  21.         Dim XMLout As String = XML.Substring(0, pos1)
  22.         XMLout += TextBox1.Text
  23.         XMLout += XML.Substring(pos2 + NodoOUT.Length)
  24.         File.WriteAllText("XUSBmod.XML", XMLout)
  25.     End Sub
  26.  
  27.     Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
  28.         ' modifica PaletteRemap0
  29.         Dim NuovoValore0 = 8
  30.         TextBox1.Text = TextBox1.Text.Remove(68, 1).Insert(68, NuovoValore0)
  31.     End Sub
  32.  
  33.     Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
  34.         ' modifica PaletteRemap1
  35.         Dim NuovoValore1 = 5
  36.         TextBox1.Text = TextBox1.Text.Remove(120, 1).Insert(120, NuovoValore1)
  37.     End Sub
  38.  
  39.     Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
  40.         ' modifica PaletteRemap2
  41.         Dim NuovoValore2 = 6
  42.         TextBox1.Text = TextBox1.Text.Remove(172, 1).Insert(172, NuovoValore2)
  43.     End Sub
  44. End Class



Ho modificato il valore nella TextBox, così vedi il risultato immediato, ma se usi: testo1 il codice non cambia.



Nel secondo esempio accedo direttamente al valore da modificare:
Codice sorgente - presumibilmente VB.NET

  1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  2.         Dim NuovoValore0 = 1 ' Valore che si vuole assegnare a PaletteRemap0
  3.         Dim NuovoValore1 = 2 ' Valore che si vuole assegnare a PaletteRemap1
  4.         Dim NuovoValore2 = 3 ' Valore che si vuole assegnare a PaletteRemap2
  5.         XML = File.ReadAllText("XUSB.XML") ' carico il file
  6.  
  7.         Dim pos = XML.IndexOf("<PaletteRemap0") ' indice del nome
  8.         XML = XML.Remove(pos + 37, 1).Insert(pos + 37, NuovoValore0) ' sostituzione vecchio valore con il nuovo
  9.  
  10.         pos = XML.IndexOf("<PaletteRemap1") ' indice del nome
  11.         XML = XML.Remove(pos + 37, 1).Insert(pos + 37, NuovoValore1) ' sostituzione vecchio valore con il nuovo
  12.  
  13.         pos = XML.IndexOf("<PaletteRemap2") ' indice del nome
  14.         XML = XML.Remove(pos + 37, 1).Insert(pos + 37, NuovoValore2) ' sostituzione vecchio valore con il nuovo
  15.  
  16.         File.WriteAllText("XUSBmod.XML", XML) ' scrittura XML con i valori di PaletteRemap0/1/2 modificati
  17. End Sub



Se il valore di PaletteRemap può avere anche due o più cifre, bisogna aggiungere una riga che ne riconosca il numero delle cifre e su remove, invece di 1, bisogna mettere il numero delle cifre trovate.

Resto sempre dell'avviso che mi piacerebbe vedere come fare la stessa cosa con XmlDocuments, XmlNode, XmlNodeList e ChildNodes.

Ultima modifica effettuata da Carlo il 28/06/2021 alle 0:19


in programmazione tutto è permesso
PM Quote
Avatar
bernie (Normal User)
Pro


Messaggi: 164
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 6:02
Lunedì, 28/06/2021
Buon giorno Carlo
Questa sera vedo di provare i due esempi.
Sinceramente il secondo esempio è quello che hai tentato di fare senza successo.
Appena li provo ti faccio sapere.
Grazie e buona giornata.

PM Quote
Avatar
bernie (Normal User)
Pro


Messaggi: 164
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 22:17
Lunedì, 28/06/2021
Ciao Carlo
prima di tutto vorrei scusarmi , questa mattina ho scritto il messaggio in fretta e non mi sono reso conto che il correttore ha cambiato una parola "Sinceramente il secondo esempio è quello che hai tentato di fare senza successo", io non ero riuscito a  farlo , tu ci sei riuscito benissimo , scusa e grazie .

Ho modificato il tuo secondo esempio e adesso mi piace
Codice sorgente - presumibilmente VB.NET

  1. Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
  2.         Dim NuovoValore = 7                                             ' nuovo valore
  3.         Dim indice As Integer = 1
  4.         Dim testo As String
  5.  
  6.         While indice <= 7
  7.             XML = File.ReadAllText(" C:\Digitalframe\XUSB.xml")         ' carico il file
  8.             testo = "<PaletteRemap" & indice                            ' compongo l'indice del nome
  9.             Dim pos = XML.IndexOf(testo)                                ' indice del nome
  10.             XML = XML.Remove(pos + 37, 1).Insert(pos + 37, NuovoValore) ' sostituzione vecchio valore con il nuovo
  11.             File.WriteAllText("C:\Digitalframe\XUSB.xml", XML)          ' scrittura XML con i valori di PaletteRemap modificati
  12.             indice += 1
  13.         End While
  14.  
  15.     End Sub


Devo riscrivere ogni volta lo stesso file, altrimenti mi ritrovo che ha modificato solo l'ultima voce . Ma questo non è un problema , anzi, a pensarci deve essere cosi .

Ogni suggerimento è ben accetto .
Grazie di nuovo  

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 22:42
Lunedì, 28/06/2021
Bravo, ma si può evitare di scrivere e leggere 8 volte il file per scrivere tutti sette:
Codice sorgente - presumibilmente VB.NET

  1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  2.         XML = File.ReadAllText("C:\Digitalframe\XUSB.xml") ' carico il file
  3.         Dim pos As Integer = 0 ' lo uso anche come startindex, ricerca in sequenza
  4.         For p = 0 To 7
  5.             pos = XML.IndexOf("<PaletteRemap" & p.ToString, pos) ' indice del nome progressivo
  6.             XML = XML.Remove(pos + 37, 1).Insert(pos + 37, 7.ToString) ' sostituzione con 7
  7.         Next
  8.         File.WriteAllText("C:\Digitalframe\XUSB.xml", XML)
  9. End Sub


Ultima modifica effettuata da Carlo il 29/06/2021 alle 0:10


in programmazione tutto è permesso
PM Quote
Avatar
bernie (Normal User)
Pro


Messaggi: 164
Iscritto: 23/10/2019

Segnala al moderatore
Postato alle 23:25
Lunedì, 28/06/2021
In realtà, il primo deve sempre essere a 0. Gli altri 7 possono variare da 1 a 7.
Non l'ho capito bene, domani dal PC me lo studio. Se pos lo setto a 1 e il ciclo for lo inizio da 1, dovrei essere a posto.
Grazie Carlo, domani me lo studio.

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1344
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 23:51
Lunedì, 28/06/2021
I valori li puoi mettere in un array, se il primo deve essere 0 lo imposti a zero:
Codice sorgente - presumibilmente VB.NET

  1. Dim valori(7) As Integer
  2. valori(0) = 0 'il vlore che andrà su PaletteRemap0
  3. valori(1) = 7 'il vlore che andrà su PaletteRemap1
  4. '...
  5. valori(7) = 7 'il vlore che andrà su PaletteRemap7
  6. Dim pos as integer = 0
  7. For p = 0 To 7
  8.         pos = XML.IndexOf("<PaletteRemap" & p.ToString, pos) ' indice del nome progressivo
  9.         XML = XML.Remove(pos + 37, 1).Insert(pos + 37, valori(p)) ' sostituzione con il valore voluto
  10. Next



Il pos su: XML.IndexOf("<PaletteRemap" & p.ToString, pos)
serve ad indicare ad IndexOf la posizione di ricerca di partenza, se viene omesso la ricerca avviene sempre dall'inizio.

Ultima modifica effettuata da Carlo il 29/06/2021 alle 0:09


in programmazione tutto è permesso
PM Quote
Pagine: [ 1 2 3 ] Precedente | Prossimo