FAQ C#Consultez toutes les FAQ

Nombre d'auteurs : 41, nombre de questions : 272, dernière mise à jour : 16 août 2017  Ajouter une question

 

Cette FAQ a été réalisée pour répondre aux questions les plus fréquemment posées concernant C# sur le forum Développement DotNET

Je tiens à souligner qu'elle ne garantit en aucun cas que les informations qu'elle contient sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci .

Sur ce, je vous souhaite une bonne lecture.

Commentez cette FAQ : Commentez


SommaireFichiers et donnéesXML (3)
précédent sommaire suivant
 

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 :

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
<Recordbook> 
	<Records> 
		<Record> 
			<FirstValue>10</FirstValue> 
			<SecondValue>51</SecondValue> 
		</Record> 
		<Record> 
			<FirstValue>25</FirstValue> 
			<SecondValue>38</SecondValue> 
		</Record> 
	</Records> 
</Recordbook>
Son implémentation :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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 :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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.

Code c# : Sélectionner tout
nav.Select("Recordbook/Records/Record");
et

Code c# : Sélectionner tout
nav.Select("Recordbook/Records/record");
ne représentent pas la même chose

Mis à jour le 5 septembre 2006 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 :

Code xml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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 :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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; 
        } 
    } 
}

Mis à jour le 22 août 2006 StormimOn

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 :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
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.

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
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 :

Code : Sélectionner tout
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 :

Code c# : Sélectionner tout
1
2
[XmlIgnore] 
public MaClasse Parent { get; set; }

Mis à jour le 10 juin 2008 Jérôme Lambert tomlev

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez 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'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsable bénévole de la rubrique Microsoft DotNET : Hinault Romaric -