Aide sur fonctionnement XML : écraser une valeur dans un fichier existant [Résolu]

Signaler
Messages postés
8
Date d'inscription
dimanche 17 juin 2007
Statut
Membre
Dernière intervention
19 octobre 2012
-
Messages postés
8
Date d'inscription
dimanche 17 juin 2007
Statut
Membre
Dernière intervention
19 octobre 2012
-
Bonjour,
Après avoir cherché sans succès sur le net (faut dire que je sais pas trop ce que je cherche...), je me décide enfin a poser la question ici.

Voila mon soucis, j'ai un fichier XML qui viens de la sérialisation d'une structure :

<?xml version="1.0" encoding="utf-16"?>
<SérieInfoDeBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <NomTVDBSérie>Alphas</NomTVDBSérie>
  <TVDBSerieID>210841</TVDBSerieID>
  <LangueUtilisée>en</LangueUtilisée>
  <DernierEpisodeVue>S02E10</DernierEpisodeVue>
  <SérieEnPause>false</SérieEnPause>
  <DateMaj>1349716376</DateMaj>
  0


</SérieInfoDeBase>


Et je doit changer par exemple la valeur de "DernierEpisodeVue", comment faire ? Effacer complétement le fichier et en écrire un nouveau ? Existe t'il une fonction, un mode overwrite ou quelque chose du genre ?

J'utilise le code suivant pour ce faire : (exemple du MSDN si ma memoire est bonne)
                    Dim serializer As New XmlSerializer(GetType(SérieInfoDeBase))
                    With InfoSérie
                        .NomTVDBSérie = NomSérie
                        .TVDBSerieID = IDSérie
                        .LangueUtilisée = LangueUtilisée
                        .DernierEpisodeVue = DernierEpisodeVue
                        .SérieEnPause = False
                        .DateMaj = DateServeur
                        .PosDerniereLecture = 0
                    End With
                    Dim fs As New FileStream(NomFichier, FileMode.Create)
                    Dim writer As New XmlTextWriter(fs, Encoding.Unicode)
                    writer.Formatting = Formatting.Indented
                    serializer.Serialize(writer, InfoSérie)
                    writer.Close()


Voila pour l'explication qui j’espère est clair. Comme vous l'aurez surement compris je viens de passer il y as peu au XML après de très bon services rendus par les fichiers ini !

Merci pour votre aide future (enfin j’espère)

6 réponses

Messages postés
3172
Date d'inscription
dimanche 15 février 2004
Statut
Membre
Dernière intervention
9 avril 2017
30
En faite, ta solution fait de même. A savoir, lire le ficher XML, modifier la valeur du nœud et réécrire tout le fichier. La modification de ficher est possible qu'en ajoutant des données à la fin.
Ta méthode marche mais ne passe pas par la sérialisation. A toi de choisir la plus adapté à ton application.


_____________
Kenji
Messages postés
8
Date d'inscription
dimanche 17 juin 2007
Statut
Membre
Dernière intervention
19 octobre 2012

Oula j'en ai oublié un bout, le bout de code sert bien sur a écrire et créer le fichier XML la première fois, pas du tout pour tenter de modifier une valeur du fichier.
Messages postés
3172
Date d'inscription
dimanche 15 février 2004
Statut
Membre
Dernière intervention
9 avril 2017
30
Salut,

Je pense pas qu'il y ait un autre moyen que de récrire complètement me fichier
Donc, en 3 étapes

Dim InfoSérie As SérieInfoDeBase
Dim serializer As XmlSerializer = New XmlSerializer(GetType(SérieInfoDeBase))

'Lecture 
Using reader As Stream = New FileStream(NomFichier, FileMode.Open)
  InfoSérie = CType(serializer.Deserialize(reader), SérieInfoDeBase)
  reader.Close()
End Using

'Modifications
InfoSérie.DernierEpisodeVue = "S02E11"

'Ecriture
Using writer As Stream = New FileStream(NomFichier, FileMode.Create)
  serializer.Serialize(writer, InfoSérie)
  writer.Close()
End Using


Ce code est un exemple, il faut bien sur éviter de mettre à jour le fichier à chaque changement d'une propriété mais que lorsque c'est utile

_____________
Kenji
Messages postés
8
Date d'inscription
dimanche 17 juin 2007
Statut
Membre
Dernière intervention
19 octobre 2012

Merci, mais en fouillant encore un peu j'ai trouvé un code qui permet de modifier un nœud dans un fichier. Au pire si d'autre cherche une solution aussi, je mets celle que je vais utiliser :

    Public Function ModifFichierXMLSérieInfoDeBase(ByVal CheminFichier As String, ByVal EcrireStruct As SérieInfoDeBase) As Boolean
        Dim XMLDoc As New XmlDocument

        XMLDoc.Load(CheminFichier)
        Dim NoeudParent As XmlNode = XMLDoc.GetElementsByTagName("DernierEpisodeVue").ItemOf(0).ParentNode
        Dim AncienNoeud As XmlNode = XMLDoc.GetElementsByTagName("DernierEpisodeVue").ItemOf(0)
        Dim NouvelElement As XmlElement = XMLDoc.CreateElement(AncienNoeud.Name)

        NouvelElement.InnerText = EcrireStruct.DernierEpisodeVue
        NoeudParent.ReplaceChild(NouvelElement, AncienNoeud)

        XMLDoc.Save(CheminFichier)
    End Function


Merci donc a toi et aussi a GabSoftware.
Bon et le prochain coup je chercherais un peu mieux
Messages postés
8
Date d'inscription
dimanche 17 juin 2007
Statut
Membre
Dernière intervention
19 octobre 2012

Hum...Je vois pas de fonction éditer, enfin se fait tard...

Je mets la dernière version un peu améliorée :
    Public Function ModifFichierXMLSérieInfoDeBase(ByVal CheminFichier As String, ByVal EcrireStruct As SérieInfoDeBase, ByVal MembreAModifier As String) As Boolean
        Dim Ret As Boolean = True
        Dim XMLDoc As New XmlDocument
        Dim ValeurModifiée As String = ""
        Dim ValeurMembre As [Object] = Nothing

        Try
            XMLDoc.Load(CheminFichier)
            Dim NoeudParent As XmlNode = XMLDoc.GetElementsByTagName(MembreAModifier).ItemOf(0).ParentNode
            Dim AncienNoeud As XmlNode = XMLDoc.GetElementsByTagName(MembreAModifier).ItemOf(0)
            Dim NouvelElement As XmlElement = XMLDoc.CreateElement(AncienNoeud.Name)

            Dim MembresStruct() As MemberInfo = EcrireStruct.GetType.GetMembers
            For Each Membre In MembresStruct
                If Membre.Name = MembreAModifier Then
                    ValeurMembre = EcrireStruct.GetType.InvokeMember(MembreAModifier, BindingFlags.GetField, Nothing, EcrireStruct, Nothing)
                    Exit For
                End If
            Next
            NouvelElement.InnerText = ValeurMembre
            NoeudParent.ReplaceChild(NouvelElement, AncienNoeud)
            XMLDoc.Save(CheminFichier)
        Catch
            Ret = False
        End Try
        Return Ret
    End Function


Le '.ItemOf(0)' n'est possible que parce que tout mes nœuds ont des noms différents. Mais ça colle parfaitement avec une structure sérialisée donc.
L'ajout du paramètre 'MembreAModifier' permet de définir quel membre de la structure on veut écraser dans le fichier.

Voila j’espère que ça pourrait être utile a d'autres.
Messages postés
8
Date d'inscription
dimanche 17 juin 2007
Statut
Membre
Dernière intervention
19 octobre 2012

Ha c’était trop beau pour être vrai ! (quoi que trop beau, c'est relatif...)
J'ai les données de la structure en mémoire dans mon appli, je sens qu'au finale ça vas finir par la méthode bourrin, un vieux delete du fichier et réutiliser la fonction de création.

Merci pour tes lumières !