none
Element vide XML découpé en 2 lignes! RRS feed

  • Question

  • Bonjour,

    J'ai un document XML qui est "bindé" à des textbox (WPF).
    Dim systemdata As XmlDataProvider = New XmlDataProvider()
    Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
            systemdata.Source = New Uri("fichier.xml")
            systemdata.XPath = "Base"
            Grid1.DataContext = systemdata
    End Sub
    Et il est sauvé ainsi:
    systemdata.Document.Save("fichier.xml")
    Par ailleurs, dans le code VB, je dois détecter les éléments vides à l'intérieur de ce même fichier XML. J'ouvre donc le fichier XML et je lis l'élément dont j'ai besoin et le place dans une variable:
    Dim sysname As String = ""
    Dim XmlReader As New XmlTextReader("Fichier.xml")
            While XmlReader.Read()
                If (XmlReader.NodeType = XmlNodeType.Element) Then
                    If (XmlReader.Name = "Name") Then
                        sysname = XmlReader.ReadString()
                    End If
                End If
    A la fin de l'élément, je voudrais vérifier de quoi il était rempli..et notamment si il est vide:
                If (XmlReader.Name = "Name" And XmlReader.NodeType = XmlNodeType.EndElement) Then
                    If sysname = String.Empty Then
                        MsgBox("Element Vide", 48, "Attention")
                    End If
                End If
            End While
    XmlReader.Close()
    Là, je me rend compte que les éléments vides ne sont pas détectés.
    En regardant le fichier XML de plus près, je me rend compte que lorsqu'il est sauvé (systemdata.Document.Save("fichier.xml"), il y a un reformatage qui est effectué!
    Un élément vide de ce type:
    <Name></Name>
    se voit sauvé en:
    <Name>
    </Name>
    Il y a donc vraisemblablement un CRLF (line break carriage return)...qui fait qu'il n'est pas détecté comme ""/String.Empty!?

    Ma question est donc la suivante:
    Comment puis-je prévenir le "reformatage" de mon fichier XML...et maintenir les éléments vides sur une seule ligne?

    Merci!!!
    mardi 16 octobre 2012 14:50

Réponses

  • Bonjour,

    Essayez de faire un trim de sysname.

    Normalement les caractères espace et crlf seront supprimés.

     

    Cordialement


    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !

    • Marqué comme réponse Aurel Bera mercredi 17 octobre 2012 08:02
    mardi 16 octobre 2012 17:29
  • Lyamine,

    Merci pour ta réponse qui m'a aiguillé vers cette solution:

    Dim sysname As String = "" 
    Dim XmlReader As New XmlTextReader("Fichier.xml") 
    While XmlReader.Read() 
    	If (XmlReader.NodeType = XmlNodeType.Element) Then 
    		If (XmlReader.Name = "Name") Then 
    			sysname = XmlReader.ReadString()
    			sysname = sysname.Replace(vbCr, "").Replace(vbLf, "").Replace("    ", "")
    		End If 
    	End If



    • Marqué comme réponse jmdeb mardi 16 octobre 2012 18:57
    • Modifié jmdeb mercredi 17 octobre 2012 20:53
    mardi 16 octobre 2012 18:57

Toutes les réponses

  • Bonjour,

    Essayez de faire un trim de sysname.

    Normalement les caractères espace et crlf seront supprimés.

     

    Cordialement


    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !

    • Marqué comme réponse Aurel Bera mercredi 17 octobre 2012 08:02
    mardi 16 octobre 2012 17:29
  • Lyamine,

    Merci pour ta réponse qui m'a aiguillé vers cette solution:

    Dim sysname As String = "" 
    Dim XmlReader As New XmlTextReader("Fichier.xml") 
    While XmlReader.Read() 
    	If (XmlReader.NodeType = XmlNodeType.Element) Then 
    		If (XmlReader.Name = "Name") Then 
    			sysname = XmlReader.ReadString()
    			sysname = sysname.Replace(vbCr, "").Replace(vbLf, "").Replace("    ", "")
    		End If 
    	End If



    • Marqué comme réponse jmdeb mardi 16 octobre 2012 18:57
    • Modifié jmdeb mercredi 17 octobre 2012 20:53
    mardi 16 octobre 2012 18:57
  • Juste une petite question : pourquoi vouloir formatter ainsi le Xml ? Il est bien formé dans les 2 cas.

    Si c'est pour une question d'optimisation (taille), le mieux serait dans ce cas de généré plutôt <Name />


    Richard Clark
    Consultant - Formateur .NET
    http://www.c2i.fr
    Depuis 1996: le 1er site .NET francophone

    mercredi 17 octobre 2012 07:31
  • Richard,

    Comme expliqué dans mon poste la raison est que si l'on veut faire une détection sur "le tag est-il vide", la réponse sera "non" car en sauvant le XML, Visual Studio fait passer 1 tag vide sur 2 lignes, et ce faisant ajoute: 1 Carriage Return, 1 Line Feed et 4 espaces !!

    Donc un tag n'apparait jamais comme vide!
    Un <AppPath></AppPath> devient

    et remarque entre les tags que l'on a CR LF 4 Spaces


    • Modifié jmdeb mercredi 17 octobre 2012 21:00
    mercredi 17 octobre 2012 20:52
  • Richard,

    Comme expliqué dans mon poste la raison est que si l'on veut faire une détection sur "le tag est-il vide", la réponse sera "non" car en sauvant le XML Visual Studio ajoute: 1 Carriage Return, 1 Line Feed et 4 espaces!!

    Donc un tag n'apparait jamais comme vide!



    Sinon vous avez la possibilité d'utiliser XmlWriterSettings/XmlReaderSettings lors de la lecture ou écriture du XML. Je me rappelle l'avoir utilisé sur un projet et ça marche très bien et très propre (désolé de ne pas y avoir pensé plus tôt).

    En admettant le XML suivant :

    <?xml version="1.0" encoding="utf-8"?>
    <Root>
    
    <Enfant>Hello world</Enfant>
    
    <Enfant>
    </Enfant>
    </Root>

    Si on utilise votre code, on va avoir le crlf.

    Par ailleurs avec XmlReaderSettings, on peut tout paramétrer ;) comme suit :

        Sub Main()
            Dim setting As XmlReaderSettings = New XmlReaderSettings()
            'suppression des chaines vides
            setting.IgnoreWhitespace = True
            Dim reader As XmlReader = XmlTextReader.Create("c:\test.xml", setting) 'XmlTextReader.Create("c:\test.xml")
    
            Dim sysname As String
            While reader.Read()
                If (reader.NodeType = XmlNodeType.Element) Then
                    If (reader.Name = "Enfant") Then
                        sysname = reader.Name + "='" + reader.ReadString() + "'"
                        Console.WriteLine(sysname)
                        'sysname = sysname.Replace(vbCr, "").Replace(vbLf, "").Replace("    ", "")
                    End If
                End If
            End While
            reader.Close()
            Console.ReadLine()
        End Sub

    Résultat sans XmlReaderSettings :

    Enfant='Hello world'
    Enfant='
    '

    Résultat avec XmlReaderSettings (IgnoreWhiteSpace) :

    Enfant='Hello world'
    Enfant=''

    C'est le vrai traitement à faire dans votre cas et plus clean que votre sysname.Replace etc...

    Vous pouvez en faire de même à la sauvegarde. Testez et donnez de vos nouvelles sur cette méthode.

     

    Cordialement


    Merci de valider par "Proposer comme réponse" si celle-ci répond à votre demande !






    • Modifié Lyamine mercredi 17 octobre 2012 21:51
    mercredi 17 octobre 2012 21:43
  • Tout à fait.

    Maintenant, pour lire le contenu d'un fichier Xml, le mieux est d'utiliser un XmlDocument ou un XDocument (Linq for Xml). Ce genre de soucis n'apparait pas.


    Richard Clark
    Consultant - Formateur .NET
    http://www.c2i.fr
    Depuis 1996: le 1er site .NET francophone

    jeudi 18 octobre 2012 06:43
  • Lyamine et Richard,

    Merci pour votre intervention...je ne demande pas mieux que d'utiliser XMLReader ou XMLDocument :
    j'ai utilisé un XmlDataProvider parce que j'ai un binding de ce fichier XML avec des éléments de l'interface!

    Donc comment puis-je faire, svp, pour:

    - Lire le XML chargé en mémoire par le XmlDataProvider avec un XMLReader? (ou XMLDocument)

    - Ou, si je devais faire l'inverse, binder des éléments à un XML chargé par XMLDocument?

    Un TOUT grand merci!! :)



    • Modifié jmdeb jeudi 18 octobre 2012 09:01
    jeudi 18 octobre 2012 09:00