module : programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 ›...

14
1 Proposé par :A BENDAOUD Module : Programmation site web dynamique LEÇON : MANIPULATION DES FICHIERS XML VIA .NET C# (LECTURE ET ECRITURE) Proposé par : A BENDAOUD XML Sommaire Créer un fichier XML à l’aide de Visual Studio ........................................................................................ 2 Créer un schéma à l’aide de Visual Studio .............................................................................................. 3 Les classes XmlTextReader et XmlTextWriter ......................................................................................... 5 La classe XmlDocument ........................................................................................................................... 9 XML et les dataset ................................................................................................................................. 11 Les transformations XSLT ...................................................................................................................... 12

Upload: others

Post on 28-Jun-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

1 Proposé par :A BENDAOUD

Module : Programmation site web dynamique

LEÇON : MANIPULATION DES FICHIERS XML VIA .NET C# (LECTURE ET ECRITURE)

Proposé par : A BENDAOUD

XML

Sommaire Créer un fichier XML à l’aide de Visual Studio ........................................................................................ 2

Créer un schéma à l’aide de Visual Studio .............................................................................................. 3

Les classes XmlTextReader et XmlTextWriter ......................................................................................... 5

La classe XmlDocument ........................................................................................................................... 9

XML et les dataset ................................................................................................................................. 11

Les transformations XSLT ...................................................................................................................... 12

Page 2: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

2 Proposé par :A BENDAOUD

XML (pour eXtensible Markup Language) constitue un moyen simple et standardisé

pour décrire et échanger des données entre applications, éventuellement distantes et sous

des systèmes d’exploitation différents. XML se veut en effet indépendant de ces considérations.

L’intérêt du XML ne se limite cependant pas à l’échange de données : même si,a priori, XML ne se

préoccupe pas de présentation (contrairement au HTML), la technique des transformations XML (ce

que l’on appelle XSLT) permet de présenter de différentes

manières un même document XML.

Était-il vraiment nécessaire d’inventer le XML ? Bien sûr, des fichiers binaires comme ceux créés ou

lus à la section 23.4 peuvent être échangés. En théorie, de tels fichiers peuvent être lus sur n’importe

quelle machine puisqu’il ne s’agit jamais que d’une suite de uns et de zéros. Mais ces fichiers ne

comportent aucune information quant à leur structure (format). Le programme qui lit un tel fichier

doit en effet disposer de son format précis. De plus, il doit savoir comment sont représentés les

entiers, les chaînes de caractères, les réels, etc., sur la machine d’origine. L’architecture .NET a certes

unifié cette représentation des types mais cette standardisation est limitée à .NET. Même avec .NET,

notre problème initial n’est toujours pas résolu puisqu’un fichier binaire créé sous .NET ne comporte

aucune information quant à son format, ce qui limite les possibilités d’échange.

XML, qui est normalisé par le World Wide Web Consortium (W3C, le consortium de normalisation

d’Internet), a adopté le format des fichiers de texte et la technique des balises.

XML n’a cependant pas que des avantages : il est pour le moins verbeux, avec une transmission de

texte délimité par des balises. Ainsi, transmettre un entier codé sur deux octets réclame

généralement la transmission d’une vingtaine de caractères. Il en résulte un coût, souvent important,

en termes de performance.

Microsoft accorde manifestement beaucoup d’importance à XML. Pour preuve, XML est omniprésent

dans .NET : fichiers de configuration, fichiers de projet, etc. Il est également utilisé pour le transfert

de datasets.

On suppose, dans ce chapitre, que les quelques règles, très simples d’ailleurs, de formatage de

fichiers XML sont connues.

Créer un fichier XML à l’aide de Visual Studio Voyons directement comment créer un fichier XML avec Visual Studio : Explorateur de

solutions clic droit sur le nom du projet Ajouter un nouvel élément et sélectionnez

Fichier XML :

Page 3: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

3 Proposé par :A BENDAOUD

Par défaut, le fichier XML à créer s’appelle XMLFile1.xml. Donnez-lui évidemment un nom plus

significatif (par exemple Pays.xml). L’éditeur XML est alors affiché. Il a déjà

préparé la ligne d’en-tête :

<?xml version="1.0" encoding="utf-8" ?>

Complétez le fichier XML, au moins pour une première entrée (comme l’éditeur ajoute

automatiquement les balises de fermeture à partir de la balise d’ouverture, surveillez ce qui se passe

à l’écran lors de la frappe) :

<?xml version="1.0" encoding="utf-8" ?>

<geo>

<pays Nom="France" Capitale="Paris" Habitants="61" />

</geo>

Vous pouvez maintenant passer en mode grille (partie droite de la figure 26-1) par clic droit

Afficher la grille de données, l’éditeur prenant alors la forme d’un tableur, et clic droit

Afficher le code pour revenir à l’état initial :

Vous pouvez ajouter des données en mode Données, le fichier XML étant automatiquement

mis à jour (vous pouvez le vérifier en repassant en mode XML).

Créer un schéma à l’aide de Visual Studio À ce fichier XML, vous pouvez associer un schéma (fichier d’extension .xsd) dans lequel on spécifie

des contraintes. Pour cela : le fichier XML étant affiché en mode XML, activez le menu XML Créer

un schéma. Passez à la fenêtre Explorateur de solutions et constatez qu’un fichier Pays.xsd a été créé

(même nom que le fichier XML mais extension .xsd).

Page 4: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

4 Proposé par :A BENDAOUD

À partir de là, vous pouvez passer à une représentation graphique : clic droit Concepteur

de vues (figure 26-3).

La lettre E indique qu’il s’agit d’un élément (on trouverait A pour un attribut). Par défaut, tous les

éléments sont de type string (l’éditeur XML ne pouvait pas deviner que le nombre d’habitants doit

être un entier positif). Pour spécifier un type plus approprié (par exemple positiveInteger pour

habitants), cliquez sur string et choisissez le type dans la liste déroulante. Pour indiquer qu’un

élément est requis (une valeur devra alors toujours être spécifiée), passez à la représentation XML et

donnez à minOccurs la valeur "1" pour cet élément. Prenez l’habitude de valider le schéma après

toute modification : passez en mode XML et activez le menu Schéma Valider schéma.

Les données sont maintenant automatiquement validées, les éventuelles erreurs apparaissant dans

la fenêtre Liste des erreurs au bas de la fenêtre.

Nous avons créé un document XML, nous lui avons éventuellement associé un schéma, nous l’avons

rempli de données et nous avons éventuellement validé ce document. Il nous faut maintenant

apprendre comment accéder aux données par programme. Deux techniques sont possibles :

le parcours noeud après noeud, un noeud à la fois grâce aux classes XmlTextReader et XmlTextWriter

;

Page 5: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

5 Proposé par :A BENDAOUD

la technique DOM (Document Object Model) : tout l’arbre (puisqu’un document XML a une structure

hiérarchique) est chargé en mémoire et est validé en mémoire. Eléments et attributs se retrouvent

alors dans des collections de propriétés.

Un document XML étant semblable à une table, il est possible :

de créer un fichier XML à partir d’un dataset (méthode WriteXml appliquée au dataset) ;

de remplir un dataset à partir d’un fichier XML (méthode ReadXml).

Les classes XmlTextReader et XmlTextWriter

La classe XmlTextReader de l’espace de noms System.Xml permet de parcourir un document

XML, noeud après noeud et dans un sens uniquement (du début à la fin du fichier).

Le document XML n’est donc pas entièrement chargé en mémoire et ne peut donc être validé au

moment du chargement. Cette technique présente l’avantage d’être peu gourmande en espace

mémoire puisqu’on n’amène jamais qu’un élément ou un attribut à la fois.

Pour utiliser cette technique, un objet XmlTextReader doit d’abord être instancié :

using System.Xml; ..... XmlTextReader rdr; ..... rdr = new XmlTextReader("geo.xml");

Une boucle rdr.Read() permet alors de lire les balises une à une. Pour chaque balise, on examine son

type (propriété NodeType). S’il s’agit d’un élément avec attributs (la propriété HasAttribute vaut alors

true), rdr.MoveToNextAttribute() permet de lire les attributs un à un (nom de l’attribut dans rdr.Name

et valeur dans rdr.Value). La fonction rdr.MoveToNext-Attribute renvoie false quand il n’y a plus

d’attribut à lire pour cet élément.

Quand le noeud est de type Element, la propriété Name contient le nom de la balise. Le rdr.Read

suivant fournit alors un noeud de type Text (sauf s’il s’agit d’une balise vide) avec le contenu de la

balise dans la propriété Value.

rdr.Read renvoie false quand il n’y a plus de balise à lire.

Classe XmlTextReader

XmlTextReader XmlReader Object

using System.Xml;

Page 6: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

6 Proposé par :A BENDAOUD

Pour illustrer l’utilisation de la classe XmlTextReader, considérons le fichier XML suivant :

Page 7: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

7 Proposé par :A BENDAOUD

<?xml version="1.0" ?> <géo> <pays Etat="République"> <nom>France</nom> <capitale>Paris</capitale> <habitants>61</habitants> </pays> <pays Etat="République"> <nom>Grèce</nom> <capitale>Athènes</capitale> <habitants>10</habitants> </pays> <pays Etat="Royauté"> <nom>Espagne</nom> <capitale>Madrid</capitale> <habitants>40</habitants> </pays> </géo>

Remarquons d’abord que ce fichier contient des lettres accentuées. Si vous avez utilisé le

bloc-notes pour créer ce fichier, il est important de le sauvegarder au format UTF-8.

À chaque ligne du tableau suivant, on exécute une instruction (rdr.Read() ou rdr.MoveTo-

NextAttribute) et on affiche différentes propriétés de l’objet rdr.

Page 8: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

8 Proposé par :A BENDAOUD

Et ainsi de suite pour les éléments suivants.

Passons maintenant à la création d’un fichier XML.

Pour créer par programme un document XML, on écrit par exemple (en se limitant ici à

la première occurrence de pays) :

Page 9: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

9 Proposé par :A BENDAOUD

using System.Xml; using System.Text; ..... XmlTextWriter wr = new XmlTextWriter("Geo.xml", Encoding.UTF8); wr.Formatting = Formatting.Indented; wr.WriteStartDocument(true); wr.WriteStartElement("géo"); wr.WriteStartElement("pays"); wr.WriteAttributeString("Etat", "République"); wr.WriteElementString("nom", "France"); wr.WriteElementString("capitale", "Paris"); wr.WriteElementString("habitants", "59"); wr.WriteEndElement(); wr.WriteEndDocument(); wr.Flush(); wr.Close();

La classe XmlDocument La classe XmlDocument implémente ce que l’on appelle la norme W3C Document Object Model

(DOM). Le DOM consiste en une représentation en mémoire et sous forme d’arbre d’un document

XML (ce dernier peut provenir d’un fichier ou même d’une chaîne de caractères du programme). Lors

du chargement, les fonctions Load (pour le chargement d’un fichier) ou LoadXml (pour le

chargement à partir d’une variable en mémoire) effectuent une vérification de syntaxe XML. Une

exception est générée en cas d’erreur.

La classe XmlDocument est dérivée de XmlNode et chaque nœud de l’arbre est lui-même un

objet XmlNode.

Passons en revue les opérations à effectuer pour parcourir un arbre. Tout l’arbre étant chargé en

mémoire suite à Load ou LoadXml, on n’est plus obligé de parcourir l’arbre nœud après nœud.

Pour ouvrir un document XML, il suffit d’écrire :

using System.Xml; ..... XmlDocument doc; ..... doc = new XmlDocument(); doc.Load("geo.xml");

// fichier du répertoire courant Load est donc toujours exécutée dans un try/catch.

//Le document XML pourrait provenir d’une variable en mémoire : string s = @"<?xml version=‘1.0’ ?> <geo>

<pays Etat=‘République’> <nom>France</nom> <capitale>Paris</capitale> <habitants>59</habitants> </pays> </geo>"; doc.LoadXml(s);

La propriété ChildNodes de l’objet doc donne accès à la collection des nœuds du document :

Page 10: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

10 Proposé par :A BENDAOUD

la balise <?xml ainsi que la racine (geo dans notre cas). Dans notre cas, doc.ChildNodes[1]

donne accès à la racine geo.

L’élément geo contient zéro, une ou plusieurs occurrences de l’élément pays. doc.Child-

Nodes[1] fait donc référence à la balise geo tandis que doc.ChildNodes[1].ChildNodes fait

référence à la collection de noeuds sous la balise geo. Pour parcourir les différentes occurrences

de pays, on écrit donc :

foreach (XmlNode n in doc.ChildNodes[1].ChildNodes)

.....

Pour déterminer si un noeud n a un attribut (par exemple Etat="République"), il suffit de

tester n.HasAttributes. Dans l’affirmative, n.Attributes fait référence à la collection des

attributs du noeud. Chaque attribut est de type XmlAttribute. Pour afficher les attributs

(nom et valeur) du premier pays (on utilise ici plusieurs objets XmlNode pour améliorer la

lisibilité mais on pourrait s’en passer) :

XmlNode nodeGeo = doc.ChildNodes[1]; // fait référence à la racine geo

// nodeFrance va faire référence à l’élément pays pour la France

XmlNode nodeFrance = nodeGeo.ChildNodes[0];

foreach (XmlAttribute att in nodeFrance.Attributes)

s += att.Name + " : " + att.Value + " --- ";

Dans notre cas, s contient Etat : République ---.

La boucle foreach aurait pu être écrite à l’aide d’un for sachant que nodeFrance.Attributes.

Count donne le nombre d’attributs de l’élément nodeFrance et que nodeFrance.Attributes[

i].Name et nodeFrance.Attributes[i].Value donnent respectivement le nom et la

valeur du i-ième attribut (une exception étant générée si ce i-ième attribut n’existe pas).

Pour afficher tous les éléments de l’élément pays dans le cas de la France (sans oublier

que certains éléments pourraient être absents pour certains pays) :

foreach (XmlNode n in nodeFrance.ChildNodes) s += n.Name + " ";

s contient nom capitale habitants.

Pour copier dans s la capitale de la France (deuxième noeud sous l’élément pays dans le cas de la

France) :

Page 11: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

11 Proposé par :A BENDAOUD

XmlNode n = nodeFrance.ChildNodes[1];

s = "La capitale de la " + n.Name + " est " + n.InnerText;

nodeFrance.ChildNodes.Count donne le nombre (ici trois) d’éléments sous l’élément node-

France (balise pays pour la France).

n.HasChildNodes indique si le noeud n a des enfants. Dans la négative, n.ChildNodes.Count

vaut zéro. Dans l’affirmative, n.ChildNodes[i], également de type XmlNode, fait référence

au i-ième noeud enfant de n (en supposant que ce i-ième noeud enfant existe, sinon une

exception est générée).

XML et les dataset

Un document XML étant semblable à une table, il est possible de créer un document XML à partir

d’un dataset : il suffit d’exécuter la fonction WriteXml appliquée à l’objet dataset. Par exemple (soyez

attentif à spécifier le chemin complet du fichier car il n’est pas, par défaut, créé dans le répertoire

courant de l’application) :

DataSet oDS;

..... // remplir le dataset

oDS.WriteXml("@c:\data\Fich.xml");

Un dataset peut être automatiquement chargé en données à partir d’un document XML :

DataSet oDS = new DataSet();

oDS.ReadXml("Fich.xml");

Dans le cas d’un programme ASP.NET, il faut écrire (par exemple dans Page_Load, le

fichier XML se trouvant dans le répertoire de l’application ASP.NET) :

oDS.ReadXml(MapPath("Fich.xml"));

On pourrait aussi écrire, en créant un stream et en le passant en

argument à ReadXml :

FileStream fs = new FileStream(MapPath("Fich.xml"),

FileMode.Open, FileAccess.Read);

StreamReader rdr = new StreamReader(fs);

DataSet oDS = new DataSet();

Page 12: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

12 Proposé par :A BENDAOUD

oDS.ReadXml(rdr);

fs.Close();

On a alors accès au dataset via l’objet oDS,.

Les transformations XSLT La technique des transformations XSLT (pour eXtensible Stylesheet Language Transformation)

permet de créer un flux de sortie (généralement du HTML) à partir d’un document

XML.

L’étude de la syntaxe XSLT sort du cadre de cet ouvrage mais nous allons prendre un

exemple simple pour illustrer la technique.

Partons du fichier XML suivant :

On crée le fichier de transformation suivant :

Fichier XML (Fich.xml)

<?xml version="1.0" ?> <geo> <pays Etat="république"> <nom>France</nom> <capitale>Paris</capitale> <habitants>61</habitants> </pays> <pays Etat="royauté"> <nom>Espagne</nom> <capitale>Madrid</capitale> <habitants>40</habitants> </pays> <pays Etat="république"> <nom>Italie</nom> <capitale>Rome</capitale> <habitants>57</habitants> </pays> </geo>

On crée le fichier de transformation suivant :

Fichier de transformation (Fich.xsl)

<?xml version="1.0" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" > <xsl:template match="géo" > <html> <body> <xsl:apply-templates /> </body> </html> </xsl:template> <xsl:template match="pays" > <span style="font-size:30pt;color:red" > <xsl:value-of select="nom" /> </span> <br/> Sa capitale est <xsl:value-of select="capitale" /> . Nombre d’habitants :

Page 13: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

13 Proposé par :A BENDAOUD

<xsl:value-of select="habitants" /> millions<br/> Il s’agit d’une <xsl:value-of select="@Etat" /> <br/><br/> <hr/> </xsl:template> </xsl:stylesheet>

Ce fichier indique comment transformer le document XML :

•quand l’élément géo est rencontré, il faut générer :

<html>

<body>

</body>

</html>

• <xsl:apply-templates /> dans body indique que le contenu de la balise body dépend des

éléments directement sous cette balise géo (ici des occurrences de pays). Pour chaque

élément pays, il faut générer :

– une balise HTML span (de manière à pouvoir spécifier une police de caractères et

une couleur d’affichage pour du texte) ;

– afficher ensuite le contenu de l’élément nom et puis un saut de ligne (balise br) ;

– du texte sans attribut particulier : Sa capitale est ;

– le contenu de l’élément capitale ;

– le texte . Nombre d’habitants : ;

– le contenu de l’élément habitants ;

– le texte millions suivi d’un saut de ligne ;

– le texte Il s’agit d’une ;

– le contenu de l’attribut Etat (il faut préfixer les noms d’attributs de @) ;

– deux sauts de ligne et une ligne de séparation (balise HTML hr).

Il reste à écrire le code de la page Web (dans un fichier d’extension .aspx). On n’y trouvera

aucune balise de présentation puisque le code de transformation s’en charge. Dans

Page_Load (voir le chapitre 28), il suffit de spécifier :

• les fichiers xml et xsl à prendre en compte ;

Page 14: Module : Programmation site web dynamiquebendaoud.e.b.f.unblog.fr › files › 2012 › 03 › LIRE_XML_DOTNET.pdf · 2012-03-01 · de ée un fihie XML à pati d’un dataset (méthode

14 Proposé par :A BENDAOUD

• la transformation à effectuer et l’envoi du résultat dans Response.Output (qui désigne le

flux de sortie HTML).

Programme ASP.NET (xslt.aspx)

<%@ Import Namespace="System.Xml" %> <%@ Import Namespace="System.Xml.Xsl" %> <script language="c#" runat="server" > public void Page_Load(Object sender, EventArgs e) { string xmlFich=MapPath("Fich.xml"); string xslFich= MapPath("Fich.xsl"); XmlDocument doc = new XmlDocument(); doc.Load(xmlFich); XslTransform xfm = new XslTransform(); xfm.Load(xslFich); XmlTextWriter writer = new XmlTextWriter(Response.Output); xfm.Transform(doc, null, writer); } </script>

Le navigateur Web affiche (voir figure ) :