Accueil
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi Eclipse MS-Office SQL & SGBD Oracle  4D  Business Intelligence
logo



Comment lire un fichier Xml avec les classes de l'espace de noms System.Xml.Xpath ?
auteur : StormimOn
Voici un exemple basique de lecture d'un fichier Xml en se servant non pas de la classe XmlDocument mais des classes de l'espace de noms System.Xml.Xpath. Deux cas sont distingués, les fichiers Xml de base et ceux avec un espace de noms.
1 Fichier Xml basique :

          
<Recordbook>
	<Records>
		<Record>
			<FirstValue>10</FirstValue>
			<SecondValue>51</SecondValue>
		</Record>
		<Record>
			<FirstValue>25</FirstValue>
			<SecondValue>38</SecondValue>
		</Record>
	</Records>
</Recordbook>
        
Son implémentation :

          
		using System.Xml.XPath;
		...
		
        private void TraiteXml()
        {
            XPathDocument doc = new XPathDocument(fileName);
            XPathNavigator nav = doc.CreateNavigator();
            // On récupère un XPathNodeIterator sur les Record
            XPathNodeIterator iter = nav.Select("Recordbook/Records/Record");
            // Pour chaque Record
            while (iter.MoveNext())
            {
                // On récupère l'info FirstValue
                string firstValue = iter.Current.SelectSingleNode("FirstValue").Value;
                // On récupère l'info SecondValue
                string secondValue = iter.Current.SelectSingleNode("SecondValue").Value;
            }
        }

        
2. Fichier Xml avec un espace de noms

          
<?xml version="1.0" encoding="utf-8"?>
<rd:Recordbook xmlns:rd="http://myexemple/myschema/record">
	<rd:Records>
		<rd:Record>
			<rd:FirstValue>10</rd:FirstValue>
			<rd:SecondValue>51</rd:SecondValue>
		</rd:Record>
		<rd:Record>
			<rd:FirstValue>25</rd:FirstValue>
			<rd:SecondValue>38</rd:SecondValue>
		</rd:Record>
	</rd:Records>
</rd:Recordbook>

        
Son implémentation :

          
		using System.Xml;
		using System.Xml.XPath;
		...

        private void TraiteXml()
        {
            XPathDocument doc = new XPathDocument(fileName);
            XPathNavigator nav = doc.CreateNavigator();
            // On ajoute la gestion des espaces de noms
            XmlNamespaceManager mgr = new XmlNamespaceManager
            (nav.NameTable);
            mgr.AddNamespace("rd", "http://myexemple/myschema/record");
            // On récupère un XPathNodeIterator sur les Record
            XPathNodeIterator iter = nav.Select
            ("rd:Recordbook/rd:Records/rd:Record", mgr);
            // Pour chaque Record
            while (iter.MoveNext())
            {
                // On récupère l'info FirstValue
                string firstValue = iter.Current.SelectSingleNode("rd:FirstValue", mgr).Value;
                // On récupère l'info SecondValue
                string secondValue = iter.Current.SelectSingleNode("rd:SecondValue", mgr).Value;
            }
        }


        
Remarque : attention, XPath est sensible à la casse. Le nom des balises doit correspondre exactement.
nav.Select("Recordbook/Records/Record");
et
nav.Select("Recordbook/Records/record");
ne représentent pas la même chose


Comment créer un XmlNamespaceManager en se basant sur un fichier Xml ?
auteur : StormimOn
Précédemment, nous avons vu comment lire un fichier avec les classes XPath. Dans le cas de la présence de namespace dans le fichier Xml, nous avons utilisé la classe XmlNamespaceManager pour gérer ces espace de noms. Le seul défaut c'est que nous alimentions manuellement ces données, nous allons donc maintenant créer ce XmlNamespaceManager de manière automatique.
Fichier Xml utilisé pour l'exemple :

          
<?xml version="1.0" encoding="utf-8"?>
<rd:Recordbook xmlns:rd="http://myexemple/myschema/record">
	<rd:Records>
		<rd:Record>
			<rd:FirstValue>10</rd:FirstValue>
			<rd:SecondValue>51</rd:SecondValue>
		</rd:Record>
		<rd:Record>
			<rd:FirstValue>25</rd:FirstValue>
			<rd:SecondValue>38</rd:SecondValue>
		</rd:Record>
	</rd:Records>
</rd:Recordbook>

        
Son implémentation :

          
		using System.Collections.Generic;
		using System.Xml;
		using System.Xml.XPath;
					...
        private XmlNamespaceManager GetXmlNamespaceManager(XPathNavigator nav)
        {
            XmlNamespaceManager mgr = null;

            nav.MoveToFirstChild();
            foreach (KeyValuePair<string, string> keyPair in nav.GetNamespacesInScope(XmlNamespaceScope.Local))
            {
                if (mgr == null)
                {
                    mgr = new XmlNamespaceManager(nav.NameTable);
                }
                mgr.AddNamespace(keyPair.Key, keyPair.Value);
            }
            nav.MoveToRoot();

            return mgr;
        }

        private void TraiteXml(string fileName)
        {
            XPathDocument doc = new XPathDocument(fileName);
            XPathNavigator nav = doc.CreateNavigator();
            XmlNamespaceManager mgr = GetXmlNamespaceManager(nav);
            if (mgr != null)
            {
                XPathNodeIterator iter = nav.Select("rd:Recordbook/rd:Records/rd:Record", mgr);
                while (iter.MoveNext())
                {
                    string firstValue = iter.Current.SelectSingleNode("rd:FirstValue", mgr).Value;
                    string secondValue = iter.Current.SelectSingleNode("rd:SecondValue", mgr).Value;
                }
            }
        }

        

Comment sérialiser un objet en XML en ignorant les références circulaires ?
auteurs : cardi, tomlev
Prenons le cas d'une classe MaClasse, qui représente un "n?ud" d'une hiérarchie. Chaque n?ud à un parent et des enfants :

          
        public class MaClasse
        {
            public MaClasse()
            {
            	Enfants = new List<MaClasse>();
            }
        
            public MaClasse Parent { get; set; }
            public List<MaClasse> Enfants { get; set; }
        }
        
Dans ce cas de figure, un parent référencera ses enfants, qui eux-même référenceront leur parent : on a donc une référence circulaire, les objets se référencent mutuellement. Si on essaie de sérialiser des objets qui ont des références circulaires, on obtient une erreur à l'exécution.

          
		MaClasse parent = new MaClasse();
		MaClasse enfant1 = new MaClasse();
		MaClasse enfant1 = new MaClasse();

		parent.Enfants.Add(enfant1);
		enfant1.Parent = parent;
		parent.Enfants.Add(enfant2);
		enfant2.Parent = parent;
		
		Serialize(parent);
	
        
Le code ci-dessus génèrera le message d'erreur suivant :
Référence circulaire détectée lors de la sérialisation d'un objet de type ConsoleApplication1.MaClasse.
Afin d'éviter ce problème, il suffit d'ignorer une des références lors de la sérialisation, de façon à ce que les références ne se fassent que dans un sens, en l'occurrence du parent vers les enfants. On va pour cela appliquer l'attribut System.Xml.Serialization.XmlIgnore à la propriété Parent :

          
[XmlIgnore]
public MaClasse Parent { get; set; }

        
lien : fr L'attribut XmlIgnore (tutoriel Developpez.com)
lien : fr System.Xml.Serialization.XmlIgnoreAttribute (MSDN)


Consultez les autres F.A.Q's


Les sources présentés sur cette page sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright ©2010  Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.

Vos questions techniques : forum d'entraide Accueil - Publiez vos articles, tutoriels, cours et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones. Nous contacter - Copyright 2000..2005 www.developpez.com