Tutorial : Linq to Xml

 01/01/2019 |   Admin |  ASP MVC


Ce tutorial a pour but de montrer comment manipuler un fichier à l'aide de Linq to Xml.

A travers cet exemple on pourra voir la création, la mise à jour, la suppression et la recherche dans un document xml.

1. Créer un nouveau site web

  • Fichier, Nouveau site web

2. Ajouter la classe Voiture

Clique droit sur le nom du site, ajouter un nouvel élément, classe : Voiture.cs

Y ajouter les propriétés suivantes :

Résultat :

//-----------------------------------------------------------------------
// <copyright file="Voiture.cs" company="CNED">
//     Copyright (c) PHN. All rights reserved.
// </copyright>
// <author>PHN</author>
// <date>07/06/2010</date>
//-----------------------------------------------------------------------
using System;
using System.ComponentModel;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
 
/// <summary>
/// Voiture Class
/// </summary>
[Serializable]
public class Voiture
{
    #region CONSTANTES
 
    /// <summary>
    /// Noeud Voiture dans le fichier XML
    /// </summary>
    public const string VOITURE = "VOITURE";
 
    /// <summary>
    /// ID dans le fichier xml
    /// </summary>
    public const string ID = "ID";
 
    /// <summary>
    /// DATE_ACHAT dans le fichier XML
    /// </summary>
    public const string DATE_ACHAT = "DATE_ACHAT";
 
    /// <summary>
    /// MARQUE dans le fichier XML
    /// </summary>
    public const string MARQUE = "MARQUE";
 
    /// <summary>
    /// POIDS dans le fichier XML
    /// </summary>
    public const string POIDS = "POIDS";
 
    /// <summary>
    /// PRIX dans le fichier XML
    /// </summary>
    public const string PRIX = "PRIX";
 
    #endregion
 
    #region CONSTRUCTEUR
 
    /// <summary>
    /// Initializes a new instance of the Voiture class
    /// </summary>
    public Voiture()
    {
    }
 
    #endregion

    #region PROPRIETES

    /// <summary>
    /// Gets or sets Id
    /// </summary>
    public long Id { get; set; }

    /// <summary>
    /// Gets or sets Marque
    /// </summary>
    public string Marque { get; set; }

    /// <summary>
    /// Gets or sets Poids
    /// </summary>
    public int Poids { get; set; }
 
    /// <summary>
    /// Gets or sets DateAchat
    /// </summary>
    public DateTime DateAchat { get; set; }

    /// <summary>
    /// Gets or sets Prix
    /// </summary>
    public double Prix { get; set; }
 
    #endregion
}

1. 3.  Ajouter la classe VoitureService.cs qui contiendra la liste des méthodes avec les méthodes suivantes :

-          GetAll

-          GetById

-          Update

-          Insert

-          Delete

-          GetByMarque

-          GetNewId

Ne pas oublier de rajouter les using suivants :

using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

  • GetAll

  •   #region GetAll
     
        /// <summary>
        /// Retourne toutes les voitures
        /// </summary>
        /// <param name="xmlFile">Le nom du fichier Xml</param>
        /// <returns>Une liste de voitures</returns>
        public IList<Voiture> GetAll(string xmlFile)
        {
            IList<Voiture> lsVoitures = null;
     
            XDocument xmlDoc = XDocument.Load(xmlFile);
     
            lsVoitures = (from voiture in xmlDoc.Descendants(Voiture.VOITURE)
                          select new Voiture
                          {
                              Id = Convert.ToInt32(voiture.Element(Voiture.ID).Value),
                              DateAchat = Convert.ToDateTime(voiture.Element(Voiture.DATE_ACHAT).Value),
                              Marque = voiture.Element(Voiture.MARQUE).Value,
                              Poids = Convert.ToInt32(voiture.Element(Voiture.POIDS).Value),
                              Prix = Convert.ToDouble(voiture.Element(Voiture.PRIX).Value)
                          }
     
                          ).ToList<Voiture>();
     
            return lsVoitures;
        }
     
        #endregion
    
  • GetById

  •  #region GetById
     
        /// <summary>
        /// Retourne une voiture en fonction de son identifiant
        /// </summary>
        /// <param name="id">Identifiant de la voiture</param>
        /// <param name="xmlFile">Emplacement du fichier Xml</param>
        /// <returns>Une voiture</returns>
        public Voiture GetById(long id, string xmlFile)
        {
            Voiture theVoiture = new Voiture();
     
            XDocument xmlDoc = XDocument.Load(xmlFile);
     
            theVoiture = (from voiture in xmlDoc.Descendants(Voiture.VOITURE)
                          where voiture.Element(Voiture.ID).Value == id.ToString()
                          select new Voiture
                          {
                              Id = Convert.ToInt32(voiture.Element(Voiture.ID).Value),
                              DateAchat = Convert.ToDateTime(voiture.Element(Voiture.DATE_ACHAT).Value),
                              Marque = voiture.Element(Voiture.MARQUE).Value,
                              Poids = Convert.ToInt32(voiture.Element(Voiture.POIDS).Value),
                              Prix = Convert.ToDouble(voiture.Element(Voiture.PRIX).Value)
                          }
     
                          ).Single<Voiture>();
     
            return theVoiture;
        }
     
        #endregion
    
     
    
  • Insert

  •  #region Insert
     
        /// <summary>
        /// Insertion d'une nouvelle voiture
        /// </summary>
        /// <param name="voiture">La nouvelle voiture</param>
        /// <param name="flux">Flux du fichier XML</param>
        /// <returns>true si ok, sinon false</returns>
        public bool Insert(Voiture voiture, string flux)
        {
            try
            {
                XElement doc = XElement.Load(flux);
     
                voiture.Id = this.GetNewId(flux);
     
                XElement newVoiture = new XElement(
        Voiture.VOITURE,
           new XElement(Voiture.ID, voiture.Id),
           new XElement(Voiture.DATE_ACHAT, voiture.DateAchat.ToString("dd/MM/yyyy")),
           new XElement(Voiture.MARQUE, voiture.Marque),
           new XElement(Voiture.POIDS, voiture.Poids),
           new XElement(Voiture.PRIX, voiture.Prix));
     
                doc.Add(newVoiture);
                doc.Save(flux);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
     
        #endregion
    
  • Update

  • #region Update
     
        /// <summary>
        /// Mise à jour d'une voiture
        /// </summary>
        /// <param name="voiture">La voiture à mettre à jour</param>
        /// <param name="flux">Flux du fichier XML</param>
        /// <returns>true si ok, sinon false</returns>
        public bool Update(Voiture voiture, string flux)
        {
            try
            {
                XDocument xmlDoc = XDocument.Load(flux);
     
                IEnumerable<XElement> theVoiture = from voit in xmlDoc.Descendants(Voiture.VOITURE)
                                                   where ((string)voit.Element(Voiture.ID)).Equals(voiture.Id.ToString())
                                                   select voit;
     
                foreach (XElement xe in theVoiture)
                {
                    xe.SetElementValue(Voiture.DATE_ACHAT, voiture.DateAchat.ToString("dd/MM/yyyy"));
                    xe.SetElementValue(Voiture.MARQUE, voiture.Marque);
                    xe.SetElementValue(Voiture.POIDS, voiture.Poids);
                    xe.SetElementValue(Voiture.PRIX, voiture.Prix);
                }
     
                xmlDoc.Save(flux);
     
                return true;
            }
            catch (Exception)
            {
                return true;
            }
        }
     
        #endregion
    
  • Delete

  • #region Delete
     
        /// <summary>
        /// Suppression d'une voiture
        /// </summary>
        /// <param name="voiture">La voiture à supprimer</param>
        /// <param name="flux">Flux du fichier XML</param>
        /// <returns>true si ok, sinon false</returns>
        public bool Delete(Voiture voiture, string flux)
        {
            try
            {
                XElement doc = XElement.Load(flux);
     
                IEnumerable<XElement> voitureToDelete =
    from voit in doc.Elements(Voiture.VOITURE)
                      where voit.Element(Voiture.ID).Value == voiture.Id.ToString()
                      select voit;
     
                foreach (XElement xe in voitureToDelete)
                {
                    xe.Remove();
                }
     
                doc.Save(flux);
     
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
     
        #endregion
    
  • GetByMarque

  • #region GetByMarque
     
        /// <summary>
        /// Retourne une voiture en fonction de sa marque
        /// </summary>
        /// <param name="marque">Marque de la voiture</param>
        /// <param name="xmlFile">Emplacement du fichier Xml</param>
        /// <returns>Une liste de voitures</returns>
        public IList<Voiture> GetByMarque(string marque, string xmlFile)
        {
            IList<Voiture> lsVoiture = null;
     
            XDocument xmlDoc = XDocument.Load(xmlFile);
     
            lsVoiture = (from voiture in xmlDoc.Descendants(Voiture.VOITURE)
                where voiture.Element(Voiture.MARQUE).Value.ToLower().Contains(marque)
                select new Voiture
                    {
            Id = Convert.ToInt32(voiture.Element(Voiture.ID).Value),
            DateAchat = Convert.ToDateTime(voiture.Element(Voiture.DATE_ACHAT).Value),
            Marque = voiture.Element(Voiture.MARQUE).Value,
            Poids = Convert.ToInt32(voiture.Element(Voiture.POIDS).Value),
            Prix = Convert.ToDouble(voiture.Element(Voiture.PRIX).Value)
                     }
     
                          ).ToList<Voiture>();
     
            return lsVoiture;
        }
     
    #endregion
    
  • GetNewId

  •  #region GetNewId
     
        /// <summary>
        /// Retourne le futur identifiant lors d'une création
        /// </summary>
        /// <param name="flux">Flux du fichier XML</param>
        /// <returns>Le nouvel identifiant</returns>
        private long GetNewId(string flux)
        {
            int nextId = 0;
     
            XDocument doc = XDocument.Load(flux);
     
            var voitures = from voiture in doc.Descendants(Voiture.VOITURE)
                           orderby (int)voiture.Element(Voiture.ID) descending
                           select new
                           {
                               newid = voiture.Element(Voiture.ID).Value,
                           };
     
            foreach (var voiture in voitures)
            {
                nextId = int.Parse(voiture.newid);
                break;
            }
     
            nextId++;
     
            return nextId;
        }
     
        #endregion
    

 

 

4. Ajouter la partie cliente, ici une page web

    • Page default.aspx
<table>
<tr>
<td align="center">
<asp:Button runat="server"
ID="btnGetAll"
Text="Obtenir toutes les voitures" OnClick="btnGetAll_Click" />
</td>
</tr>
<tr>
<td>
Recherche par marque :
<asp:TextBox runat="server" ID="txtSearchMarque"/>
<asp:Button runat="server"
ID="btnSearchMarque"
Text="Rechercher"
                        onclick="btnSearchMarque_Click"/>
</td>
</tr>
<tr>
<td>
<asp:GridView runat="server"
ID="gvVoitures"
AutoGenerateColumns="false" OnRowCommand="gvVoitures_RowCommand">
 <Columns>
  <asp:TemplateField>
   <ItemTemplate>
    <asp:Button runat="server"
ID="btnEditVoiture"
Text="Modifier"
CommandName="UpdateCar"
                             CommandArgument='<%# Eval("Id") %>' />
   </ItemTemplate>
  </asp:TemplateField>
 <asp:TemplateField>
  <ItemTemplate>
<asp:Button runat="server"
ID="btnDeleteVoiture"
Text="Supprimer"
CommandName="DeleteCar"
                             CommandArgument='<%# Eval("Id") %>' />
  </ItemTemplate>
 </asp:TemplateField>
 <asp:BoundField DataField="Marque" HeaderText="Marque" />
 <asp:BoundField DataField="Poids" HeaderText="Poids" />
 <asp:BoundField DataField="DateAchat" HeaderText="Date d'achat"
     DataFormatString="{0:dd/MM/yyyy}" />
 <asp:BoundField DataField="Prix" HeaderText="Prix" />
</Columns>
</asp:GridView>
</td>
</tr>
<tr>
<td align="center">
                    <asp:Button runat="server"
ID="btnAdd"
Text="Ajouter une voiture"
OnClick="btnAdd_Click" />
</td>
</tr>
</table>

<asp:Panel runat="server" ID="pnlDetail" Visible="false" Width="600px">
<table>
<tr>
<td style="width: 150px" align="right">
                        Marque :
</td>
<td style="width: 450px">
<asp:TextBox runat="server"
ID="txtMarque"
Width="90%"/>
</td>
</tr>
<tr>
<td align="right">
                        Poids :
</td>
<td>
<asp:TextBox runat="server"
ID="txtPoids"
Width="40%" />
</td>
</tr>
<tr>
<td align="right">
                        Date d'achat :
</td>
<td>
<asp:TextBox runat="server"
ID="txtDateAchat"
Width="40%" />
</td>
</tr>
<tr>
<td align="right">
                        Prix :
</td>
<td>
<asp:TextBox runat="server"
ID="txtPrix"
Width="40%" />
</td>
</tr>
<tr>
<td colspan="2" align="center">
<asp:Button runat="server"
ID="btnSave"
Text="Valider"
OnClick="btnSave_Click" />
</td>
</tr>
<tr>
<td colspan="2" align="center">
<asp:Label runat="server"
ID="lblErreur"
ForeColor="Red"></asp:Label>
</td>
</tr>
</table>
</asp:Panel>

 

  • CodeBehind
      • Déclaration des constantes
    #region CONSTANTES
     
        /// <summary>
        /// Nom du fichier XML
        /// </summary>
        private const string XML_FILE = "XMLFile.xml";
     
        /// <summary>
        /// Voiture en cours qui sera stockée dans un ViewState
        /// </summary>
        private const string VOITURE = "VOITURE";
     
        /// <summary>
        /// Mode actuel (update ou insert) stocké dans un ViewState
        /// </summary>
        private const string MODE = "MODE";
     
        /// <summary>
        /// Mode insert
        /// </summary>
        private const string INSERT = "INSERT";
     
        /// <summary>
        /// Mode Update
        /// </summary>
        private const string UPDATE = "UPDATE";
     
    
    #endregion
    
    
    
    • Remplir la GridView
/// <summary>
/// Remplir la grille des voitures
/// </summary>
private void FillGrid()
{
    gvVoitures.DataSource = new VoitureService().GetAll(Server.MapPath(XML_FILE));
    gvVoitures.DataBind();
}

 

    • Méthode permettant d'afficher une voiture
/// <summary>
/// Affichage d'une voiture dans le formulaire de détail
/// </summary>
private void AfficherVoiture()
{
Voiture voiture = (Voiture)ViewState[VOITURE];
txtMarque.Text = voiture.Marque;
txtPrix.Text = voiture.Prix.ToString();
txtPoids.Text = voiture.Poids.ToString();
txtDateAchat.Text = voiture.DateAchat.ToString("dd/MM/yyyy");
}

 

    • Méthode déclenchée lors de l'action sur la GridView
/// <summary>
/// RowCommand sur la grille des voitures (modification ou suppression)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void gvVoitures_RowCommand(object sender, GridViewCommandEventArgs e)
{
switch (e.CommandName)
{
case "UpdateCar":
 
ViewState[VOITURE] = new VoitureService().GetById(Convert.ToInt64(e.CommandArgument), Server.MapPath(XML_FILE));
AfficherVoiture();
pnlDetail.Visible = true;
 
ViewState[MODE] = UPDATE;
 
break;
 
case "DeleteCar":
 
Voiture voitureToDelete = new Voiture();
voitureToDelete.Id = Convert.ToInt64(e.CommandArgument);
 
new VoitureService().Delete(voitureToDelete, Server.MapPath(XML_FILE));
                FillGrid();
 
break;
}
 

}

 

    • Action sur les boutons
#region BOUTONS
 
    /// <summary>
    /// Obtenir toutes les voitures
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnGetAll_Click(object sender, EventArgs e)
    {
        FillGrid();
    }
 
    /// <summary>
    /// Bouton de sauvegarde
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnSave_Click(object sender, EventArgs e)
    {
        // Récupération du mode
        switch ((string)ViewState[MODE])
        {
            // Insertion d'une nouvelle voiture
            case INSERT:
 
                Voiture voitureToInsert = new Voiture();
 
                voitureToInsert.Marque = txtMarque.Text;
                voitureToInsert.DateAchat = Convert.ToDateTime(txtDateAchat.Text);
                voitureToInsert.Poids = Convert.ToInt32(txtPoids.Text);
                voitureToInsert.Prix = Convert.ToDouble(txtPrix.Text);
 
                new VoitureService().Insert(voitureToInsert, Server.MapPath(XML_FILE));
 
                break;
 
            // Mise à jour de la voiture
            case UPDATE:
 
                try
                {
                    // Récupération de la voiture actuelle dans le viewState
                    Voiture voitureToUpdate = (Voiture)ViewState[VOITURE];
 
                    voitureToUpdate.Marque = txtMarque.Text;
                    voitureToUpdate.DateAchat = Convert.ToDateTime(txtDateAchat.Text);
                    voitureToUpdate.Poids = Convert.ToInt32(txtPoids.Text);
                    voitureToUpdate.Prix = Convert.ToDouble(txtPrix.Text);
 
                    new VoitureService().Update(voitureToUpdate, Server.MapPath(XML_FILE));
                    lblErreur.Text = string.Empty;
                }
                catch (FormatException)
                {
                    lblErreur.Text = "Format des données incorrectes";
                }
                break;
        }
 
        FillGrid();
    }

 

/// <summary>
/// Bouton permettant d'ajouter une voiture
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnAdd_Click(object sender, EventArgs e)
{
ViewState[MODE] = INSERT;
pnlDetail.Visible = true;
 
txtMarque.Text = string.Empty;
txtPrix.Text = string.Empty;
txtPoids.Text = string.Empty;
txtDateAchat.Text = string.Empty;
}
 
    /// <summary>
    /// Bouton de recherche par marque
    /// Renvoi une liste de voitures en fonction de la marque
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnSearchMarque_Click(object sender, EventArgs e)
    {
        gvVoitures.DataSource = new VoitureService().GetByMarque(txtSearchMarque.Text.Trim().ToLower(), Server.MapPath(XML_FILE));
        gvVoitures.DataBind();
    }
 
#endregion

 

Lire >>

  • 1