LINQ to XML e DOMLINQ to XML vs. DOM

Este artigo descreve algumas das principais diferenças entre LINQ to XML e a API de programação XML predominante atual, o W3C Modelo de Objeto do Documento (DOM).This article describes some key differences between LINQ to XML and the current predominant XML programming API, the W3C Document Object Model (DOM).

Novas maneiras de construir árvores XMLNew ways to construct XML trees

No W3C DOM, você cria uma árvore XML de baixo para cima; ou seja, você cria um documento, cria elementos e, em seguida, adiciona elementos ao documento.In the W3C DOM, you build an XML tree from the bottom up; that is, you create a document, you create elements, and then you add the elements to the document.

Por exemplo, o exemplo a seguir usa uma maneira típica de criar uma árvore XML usando a implementação da Microsoft do DOM, XmlDocument .For example, the following example uses a typical way to create an XML tree using the Microsoft implementation of 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)

Esse estilo de codificação oculta a estrutura da árvore XML.This style of coding hides the structure of the XML tree. O LINQ to XML também dá suporte a uma abordagem alternativa, construção funcional, que mostra melhor a estrutura.LINQ to XML also supports an alternative approach, functional construction, that better shows the structure. Essa abordagem pode ser feita com os XElement XAttribute construtores e.This approach can be done with the XElement and XAttribute constructors. No Visual Basic, ele também pode ser feito com literais XML.In Visual Basic, it can also be done with XML literals. Este exemplo demonstra a construção da mesma árvore XML usando a construção funcional:This example demonstrates construction of the same XML tree using functional construction:

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>

Observe que o recuo do código para construir a árvore XML mostra a estrutura do XML subjacente.Notice that indenting the code to construct the XML tree shows the structure of the underlying XML. A versão Visual Basic usa literais XML.The Visual Basic version uses XML literals.

Para obter mais informações, consulte árvores XML.For more information, see XML trees.

Trabalhar diretamente com elementos XMLWork directly with XML elements

Quando você programa com XML, o foco principal é geralmente em elementos XML e talvez em atributos.When you program with XML, your primary focus is usually on XML elements and perhaps on attributes. No LINQ to XML, você pode trabalhar diretamente com elementos e atributos XML.In LINQ to XML, you can work directly with XML elements and attributes. Por exemplo, você pode fazer o seguinte:For example, you can do the following:

  • Criar elementos XML sem usar nenhum objeto de documento.Create XML elements without using a document object at all. Isso simplifica a programação quando você tem que trabalhar com partes de árvores XML.This simplifies programming when you have to work with fragments of XML trees.
  • Carregue objetos T:System.Xml.Linq.XElement diretamente de um arquivo XML.Load T:System.Xml.Linq.XElement objects directly from an XML file.
  • Serialize objetos T:System.Xml.Linq.XElement para um arquivo ou fluxo.Serialize T:System.Xml.Linq.XElement objects to a file or a stream.

Compare isso para o W3C DOM, no qual o documento XML é usado como um contêiner lógico para a árvore XML.Compare this to the W3C DOM, in which the XML document is used as a logical container for the XML tree. No DOM, os nós XML, incluindo elementos e atributos, devem ser criados no contexto de um documento XML.In DOM, XML nodes, including elements and attributes, must be created in the context of an XML document. Aqui está um fragmento de código para criar um elemento Name no DOM:Here is a fragment of code to create a name element in 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)

Se você quiser usar um elemento em vários documentos, deverá importar os nós nos documentos.If you want to use an element across multiple documents, you must import the nodes across documents. LINQ to XML evita essa camada de complexidade.LINQ to XML avoids this layer of complexity.

Ao usar LINQ to XML, você usará a classe XDocument somente se você desejar adicionar um comentário ou uma instrução de processamento no nível raiz do documento.When using LINQ to XML, you use the XDocument class only if you want to add a comment or processing instruction at the root level of the document.

Manipulação simplificada de nomes e namespacesSimplified handling of names and namespaces

Tratar nomes, namespaces e prefixos de namespace é geralmente uma parte complexa da programação de XML.Handling names, namespaces, and namespace prefixes is generally a complex part of XML programming. O LINQ to XML simplifica nomes e namespaces eliminando a necessidade de lidar com prefixos de namespace.LINQ to XML simplifies names and namespaces by eliminating the requirement to deal with namespace prefixes. Se quiser, você pode controlar prefixos de namespace.If you want to control namespace prefixes, you can. Mas se você decidir não controlar explicitamente os prefixos de namespace, LINQ to XML atribuirá prefixos de namespace durante a serialização, se eles forem necessários, ou serializarão usando namespaces padrão, se não forem.But if you decide to not explicitly control namespace prefixes, LINQ to XML will assign namespace prefixes during serialization if they're required, or will serialize using default namespaces if they're not. Se namespaces padrão forem usados, não haverá prefixos de namespace no documento resultante.If default namespaces are used, there will be no namespace prefixes in the resulting document. Para obter mais informações, consulte visão geral de namespaces.For more information, see Namespaces overview.

Outro problema com o DOM é que ele não permite que você altere o nome de um nó.Another problem with the DOM is that it doesn't let you change the name of a node. Em vez disso, você precisa criar um novo nó e copiar todos os nós filhos para ele, perdendo a identidade do nó original.Instead, you have to create a new node and copy all the child nodes to it, losing the original node identity. LINQ to XML evita esse problema permitindo que você defina a XName propriedade em um nó.LINQ to XML avoids this problem by enabling you to set the XName property on a node.

Suporte de método estático para carregar XMLStatic method support for loading XML

LINQ to XML permite carregar XML usando métodos estáticos, em vez de métodos de instância.LINQ to XML lets you load XML by using static methods, instead of instance methods. Isso simplifica o carregamento e a análise.This simplifies loading and parsing. Para obter mais informações, consulte como carregar XML de um arquivo.For more information, see How to load XML from a file.

Remoção de suporte para construções de DTDRemoval of support for DTD constructs

LINQ to XML simplifica ainda mais a programação XML removendo o suporte para entidades e referências de entidade.LINQ to XML further simplifies XML programming by removing support for entities and entity references. O gerenciamento de entidades é complexo e raramente é usado.The management of entities is complex, and is rarely used. Remover o suporte aumenta o desempenho e simplifica a interface de programação.Removing their support increases performance and simplifies the programming interface. Quando uma árvore de LINQ to XML é populada, todas as entidades DTD são expandidas.When a LINQ to XML tree is populated, all DTD entities are expanded.

Suporte para fragmentosSupport for fragments

LINQ to XML não fornece um equivalente para a XmlDocumentFragment classe.LINQ to XML doesn't provide an equivalent for the XmlDocumentFragment class. Em muitos casos, no entanto, o XmlDocumentFragment conceito pode ser tratado pelo resultado de uma consulta que é digitada a partir IEnumerable<T> de XNode , ou IEnumerable<T> de XElement .In many cases, however, the XmlDocumentFragment concept can be handled by the result of a query that's typed as IEnumerable<T> of XNode, or IEnumerable<T> of XElement.

Suporte para XPathNavigatorSupport for XPathNavigator

LINQ to XML fornece suporte para por XPathNavigator meio de métodos de extensão no System.Xml.XPath namespace.LINQ to XML provides support for XPathNavigator through extension methods in the System.Xml.XPath namespace. Para obter mais informações, consulte System.Xml.XPath.Extensions.For more information, see System.Xml.XPath.Extensions.

Suporte para espaço em branco e recuoSupport for white space and indentation

LINQ to XML lida com o espaço em branco mais simples do que o DOM.LINQ to XML handles white space more simply than the DOM.

Um cenário comum é ler XML recuado, criar uma árvore XML na memória sem nenhum nó de texto de espaço em branco (ou seja, não preservar espaço em branco), executar algumas operações no XML e, em seguida, salvar o XML com recuo.A common scenario is to read indented XML, create an in-memory XML tree without any white space text nodes (that is, not preserving white space), do some operations on the XML, and then save the XML with indentation. Quando você serializa o XML com formatação, somente os espaços em branco significativos na árvore XML são preservados.When you serialize the XML with formatting, only significant white space in the XML tree is preserved. Esse é o comportamento padrão para LINQ to XML.This is the default behavior for LINQ to XML.

Outro cenário comum é ler e modificar XML que já foi recuado intencionalmente.Another common scenario is to read and modify XML that has already been intentionally indented. Você pode não querer modificar este recuo de nenhuma forma.You might not want to change this indentation in any way. No LINQ to XML, você pode fazer isso da seguinte:In LINQ to XML, you can do this by:

  • Preservando o espaço em branco quando você carrega ou analisa o XML.Preserving white space when you load or parse the XML.
  • Desabilitar a formatação ao serializar o XML.Disabling formatting when you serialize the XML.

O LINQ to XML armazena espaço em branco como um XText nó, em vez de ter um Whitespace tipo de nó especializado, como o dom faz.LINQ to XML stores white space as an XText node, instead of having a specialized Whitespace node type, as the DOM does.

Suporte para anotaçõesSupport for annotations

LINQ to XML elementos dão suporte a um conjunto extensível de anotações.LINQ to XML elements support an extensible set of annotations. Isso é útil para acompanhar informações variadas sobre um elemento, como informações de esquema, informações sobre se o elemento está associado a uma interface do usuário ou qualquer outro tipo de informações específicas do aplicativo.This is useful for tracking miscellaneous information about an element, such as schema information, information about whether the element is bound to a UI, or any other kind of application-specific information. Para obter mais informações, consulte LINQ to XML anotações.For more information, see LINQ to XML annotations.

Suporte para informações de esquemaSupport for schema information

LINQ to XML fornece suporte para validação XSD por meio de métodos de extensão no System.Xml.Schema namespace.LINQ to XML provides support for XSD validation through extension methods in the System.Xml.Schema namespace. Você pode validar que uma árvore XML está em conformidade com XSD.You can validate that an XML tree complies with an XSD. Você pode preencher a árvore XML com o PSVI (post-schema-validation infoset).You can populate the XML tree with the post-schema-validation infoset (PSVI). Para obter mais informações, consulte como validar usando xsd e Extensions .For more information, see How to validate using XSD and Extensions.

Confira tambémSee also