LINQ to XML, différences par rapport à DOM

Cet article décrit certaines des principales différences entre LINQ to XML et l’API de programmation XML actuellement prédominante, le modèle DOM (Document Object Model) W3C.

Nouvelles manières de construire des arborescences XML

Dans le modèle DOM W3C, vous construisez une arborescence XML de bas en haut ; autrement dit, vous créez un document, vous créez des éléments, puis vous ajoutez les éléments au document.

L’exemple suivant utilise une méthode typique de création d’une arborescence XML à l’aide de l’implémentation Microsoft du modèle DOM, XmlDocument.

XmlDocument doc = new XmlDocument();
XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
XmlElement phone1 = doc.CreateElement("Phone");
phone1.SetAttribute("Type", "Home");
phone1.InnerText = "206-555-0144";
XmlElement phone2 = doc.CreateElement("Phone");
phone2.SetAttribute("Type", "Work");
phone2.InnerText = "425-555-0145";
XmlElement street1 = doc.CreateElement("Street1");
street1.InnerText = "123 Main St";
XmlElement city = doc.CreateElement("City");
city.InnerText = "Mercer Island";
XmlElement state = doc.CreateElement("State");
state.InnerText = "WA";
XmlElement postal = doc.CreateElement("Postal");
postal.InnerText = "68042";
XmlElement address = doc.CreateElement("Address");
address.AppendChild(street1);
address.AppendChild(city);
address.AppendChild(state);
address.AppendChild(postal);
XmlElement contact = doc.CreateElement("Contact");
contact.AppendChild(name);
contact.AppendChild(phone1);
contact.AppendChild(phone2);
contact.AppendChild(address);
XmlElement contacts = doc.CreateElement("Contacts");
contacts.AppendChild(contact);
doc.AppendChild(contacts);
Dim doc As XmlDocument = New XmlDocument()
Dim name As XmlElement = doc.CreateElement("Name")
name.InnerText = "Patrick Hines"
Dim phone1 As XmlElement = doc.CreateElement("Phone")
phone1.SetAttribute("Type", "Home")
phone1.InnerText = "206-555-0144"
Dim phone2 As XmlElement = doc.CreateElement("Phone")
phone2.SetAttribute("Type", "Work")
phone2.InnerText = "425-555-0145"
Dim street1 As XmlElement = doc.CreateElement("Street1")
street1.InnerText = "123 Main St"
Dim city As XmlElement = doc.CreateElement("City")
city.InnerText = "Mercer Island"
Dim state As XmlElement = doc.CreateElement("State")
state.InnerText = "WA"
Dim postal As XmlElement = doc.CreateElement("Postal")
postal.InnerText = "68042"
Dim address As XmlElement = doc.CreateElement("Address")
address.AppendChild(street1)
address.AppendChild(city)
address.AppendChild(state)
address.AppendChild(postal)
Dim contact As XmlElement = doc.CreateElement("Contact")
contact.AppendChild(name)
contact.AppendChild(phone1)
contact.AppendChild(phone2)
contact.AppendChild(address)
Dim contacts As XmlElement = doc.CreateElement("Contacts")
contacts.AppendChild(contact)
doc.AppendChild(contacts)
Console.WriteLine(doc.OuterXml)

Ce style de codage masque la structure de l’arborescence XML. LINQ to XML prend également en charge une autre approche, la construction fonctionnelle, qui montre mieux la structure. Cette approche peut être effectuée avec les constructeurs XElement et XAttribute. En Visual Basic, cela peut également être effectué avec des littéraux XML. Cet exemple illustre la construction de la même arborescence XML à l’aide de la construction fonctionnelle :

XElement contacts =
    new XElement("Contacts",
        new XElement("Contact",
            new XElement("Name", "Patrick Hines"),
            new XElement("Phone", "206-555-0144",
                new XAttribute("Type", "Home")),
            new XElement("phone", "425-555-0145",
                new XAttribute("Type", "Work")),
            new XElement("Address",
                new XElement("Street1", "123 Main St"),
                new XElement("City", "Mercer Island"),
                new XElement("State", "WA"),
                new XElement("Postal", "68042")
            )
        )
    );
Dim contacts = _
    <Contacts>
        <Contact>
            <Name>Patrick Hines</Name>
            <Phone Type="Home">206-555-0144</Phone>
            <Phone Type="Work">425-555-0145</Phone>
            <Address>
                <Street1>123 Main St</Street1>
                <City>Mercer Island</City>
                <State>WA</State>
                <Postal>68042</Postal>
            </Address>
        </Contact>
    </Contacts>

Notez que la mise en retrait du code pour construire l’arborescence XML affiche la structure des données XML sous-jacentes. La version de Visual Basic utilise des littéraux XML.

Pour plus d’informations, consultez Arborescence XML.

Utiliser directement des éléments XML

Lorsque vous programmez avec des données XML, vous travaillez en général principalement avec les éléments XML et éventuellement les attributs. Dans LINQ to XML, vous pouvez utiliser directement les éléments et les attributs XML. Vous pouvez par exemple effectuer les opérations suivantes :

  • Créer des éléments XML sans utiliser d'objet de document. Cela simplifie la programmation lorsque vous devez travailler avec des fragments d'arborescences XML.
  • Charger des objets T:System.Xml.Linq.XElement directement à partir d'un fichier XML.
  • Sérialiser des objets T:System.Xml.Linq.XElement dans un fichier ou un flux.

Comparez cela au modèle DOM W3C, dans lequel le document XML est utilisé en tant que conteneur logique pour l'arborescence XML. Dans le modèle DOM, les nœuds XML, y compris les éléments et attributs, doivent être créés dans le contexte d'un document XML. Voici un fragment de code permettant de créer un élément de nom dans le modèle DOM :

XmlDocument doc = new XmlDocument();
XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
doc.AppendChild(name);
Dim doc As XmlDocument = New XmlDocument()
Dim name As XmlElement = doc.CreateElement("Name")
name.InnerText = "Patrick Hines"
doc.AppendChild(name)

Si vous souhaitez utiliser un élément dans plusieurs documents, vous devez importer les nœuds d'un document à un autre. LINQ to XML évite cette couche de complexité.

Lors de l'utilisation de LINQ to XML, vous utilisez la classe XDocument uniquement si vous souhaitez ajouter un commentaire ou une information de traitement au niveau racine du document.

Gestion simplifiée des noms et des espaces de noms

La gestion des noms, des espaces de noms et des préfixes d'espaces de noms est généralement un aspect complexe de la programmation XML. LINQ to XML simplifie les noms et les espaces de noms en éliminant la nécessité de gérer les préfixes d’espaces de noms. Vous pouvez si vous le souhaitez contrôler les préfixes d'espaces de noms. Si vous décidez cependant de ne pas contrôler explicitement les préfixes d’espaces de noms, LINQ to XML affecte des préfixes d’espaces de noms lors de la sérialisation s’ils sont nécessaires ou, s’ils ne le sont pas, sérialise en utilisant les espaces de noms par défaut. Si des espaces de noms par défaut sont utilisés, il n'y aura pas de préfixes d'espaces de noms dans le document résultant. Pour plus d’informations, consultez Vue d’ensemble des espaces de noms.

L’un des autres problèmes associés au modèle DOM est qu’il ne vous permet pas de modifier le nom d’un nœud. Au lieu de cela, vous devez créer un nouveau nœud et y copier tous les nœuds enfants, perdant ainsi l'identité de nœud d'origine. LINQ to XML évite ce problème en vous permettant de définir la propriété XName sur un nœud.

Prise en charge des méthodes statiques pour le chargement de données XML

LINQ to XML vous permet de charger du code XML en utilisant des méthodes statiques au lieu de méthodes d’instance. Cela simplifie le chargement et l'analyse. Pour plus d’informations, consultez Guide pratique pour charger du code XML à partir d’un fichier.

Suppression de la prise en charge des constructions de DTD

LINQ to XML simplifie la programmation XML en supprimant la prise en charge des entités et des références d’entités. La gestion des entités est complexe et rarement utilisée. La suppression de leur prise en charge augmente les performances et simplifie l'interface de programmation. Quand une arborescence LINQ to XML est remplie, toutes les entités DTD sont développées.

Prise en charge des fragments

LINQ to XML ne fournit pas d’équivalent pour la classe XmlDocumentFragment. Dans de nombreux cas, cependant, le concept de XmlDocumentFragment peut être géré par le résultat d’une requête typée IEnumerable<T> de XNode ou IEnumerable<T> de XElement.

Prise en charge de XPathNavigator

LINQ to XML fournit une prise en charge pour XPathNavigator via les méthodes d’extension de l’espace de noms System.Xml.XPath. Pour plus d'informations, consultez System.Xml.XPath.Extensions.

Prise en charge des espaces blancs et de la mise en retrait

LINQ to XML gère les espaces plus simplement que le modèle DOM.

Un scénario courant consiste à lire le code XML mis en retrait, à créer une arborescence XML en mémoire sans nœuds d’espaces blancs (autrement dit, les espaces blancs ne sont pas conservés), à effectuer certaines opérations sur le code XML, puis à enregistrer le code XML avec mise en retrait. Lorsque vous sérialisez le code XML avec mise en forme, seuls les espaces significatifs dans l'arborescence XML sont conservés. Il s’agit du comportement par défaut pour LINQ to XML.

Un autre scénario courant consiste à lire et à modifier du code XML qui a déjà été intentionnellement mis en retrait. Vous ne souhaiterez peut-être modifier cette mise en retrait en aucune manière. Dans LINQ to XML, vous pouvez effectuer cette opération en procédant comme suit :

  • Conservation de l’espace blanc lorsque vous chargez ou analysez le code XML.
  • Désactivation de la mise en forme lorsque vous sérialisez le code XML.

LINQ to XML stocke les espaces en tant que nœud XText au lieu de faire appel à un type de nœud Whitespace spécialisé, comme le fait DOM.

Prise en charge des annotations

Les éléments LINQ to XML prennent en charge un ensemble extensible d’annotations. Cela est utile pour assurer le suivi de diverses informations relatives à un élément, telles que des informations de schéma, le fait que l'élément soit lié à une interface utilisateur ou tout autre type d'informations spécifiques aux applications. Pour plus d’informations, consultez Annotations LINQ to XML.

Prise en charge des informations de schéma

LINQ to XML fournit une prise en charge de la validation XSD via les méthodes d’extension de l’espace de noms System.Xml.Schema. Vous pouvez valider la conformité d’une arborescence XML à un schéma XSD. Vous pouvez remplir l’arborescence XML avec le PSVI (Post-Schema-Validation Infoset). Pour plus d’informations, consultez Guide pratique pour valider à l’aide de XSD et Extensions.

Voir aussi