Partilhar via


LINQ para XML vs. DOM

Este artigo descreve algumas diferenças importantes entre LINQ to XML e a API de programação XML predominante atual, o W3C Document Object Model (DOM).

Novas maneiras de construir árvores XML

No DOM do W3C, você cria uma árvore XML de baixo para cima; ou seja, você cria um documento, cria elementos e, em seguida, adiciona os elementos ao documento.

Por exemplo, o exemplo a seguir usa uma maneira típica de criar uma árvore XML usando a implementação Microsoft do 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. LINQ to XML também suporta uma abordagem alternativa, a construção funcional, que mostra melhor a estrutura. Esta abordagem pode ser feita com os XElement construtores e XAttribute . No Visual Basic, isso também pode ser feito com literais XML. Este exemplo demonstra a construção da mesma árvore XML usando a construção funcional:

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 recuar o código para construir a árvore XML mostra a estrutura do XML subjacente. A versão do Visual Basic usa literais XML.

Para obter mais informações, consulte Árvores XML.

Trabalhar diretamente com elementos XML

Quando você programa com XML, seu foco principal geralmente está em elementos XML e talvez em atributos. No LINQ to XML, você pode trabalhar diretamente com elementos e atributos XML. Por exemplo, você pode fazer o seguinte:

  • Crie elementos XML sem usar um objeto de documento. Isso simplifica a programação quando você precisa trabalhar com fragmentos de árvores XML.
  • Carregue T:System.Xml.Linq.XElement objetos diretamente de um arquivo XML.
  • Serialize T:System.Xml.Linq.XElement objetos para um arquivo ou um fluxo.

Compare isso com o DOM do W3C, no qual o documento XML é usado como um contêiner lógico para a árvore XML. No DOM, nós XML, incluindo elementos e atributos, devem ser criados no contexto de um documento XML. Aqui está um fragmento de código para criar um elemento name no 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 quiser usar um elemento em vários documentos, importe os nós entre documentos. LINQ to XML evita essa camada de complexidade.

Ao usar LINQ to XML, você usa a XDocument classe somente se quiser adicionar um comentário ou instrução de processamento no nível raiz do documento.

Tratamento simplificado de nomes e namespaces

A manipulação de nomes, namespaces e prefixos de namespace geralmente é uma parte complexa da programação XML. LINQ to XML simplifica nomes e namespaces eliminando a necessidade de lidar com prefixos de namespace. Se você quiser controlar prefixos de namespace, você pode. Mas se você decidir não controlar explicitamente os prefixos de namespace, o LINQ to XML atribuirá prefixos de namespace durante a serialização, se necessário, ou serializará usando namespaces padrão, se não forem. Se namespaces padrão forem usados, não haverá prefixos de namespace no documento resultante. Para obter mais informações, consulte Visão geral de namespaces.

Outro problema com o DOM é que ele não permite que você altere o nome de um nó. Em vez disso, você precisa criar um novo nó e copiar todos os nós filho para ele, perdendo a identidade do nó original. LINQ to XML evita esse problema permitindo que você defina a XName propriedade em um nó.

Suporte a método estático para carregar XML

LINQ to XML permite carregar XML usando métodos estáticos, em vez de métodos de instância. Isso simplifica o carregamento e a análise. Para obter mais informações, consulte Como carregar XML de um arquivo.

Remoção do suporte para construções DTD

O LINQ to XML simplifica ainda mais a programação XML, removendo o suporte para entidades e referências de entidades. A gestão das entidades é complexa e raramente é utilizada. Remover seu suporte aumenta o desempenho e simplifica a interface de programação. Quando uma árvore LINQ to XML é preenchida, todas as entidades DTD são expandidas.

Suporte para fragmentos

LINQ to XML não fornece um equivalente para a XmlDocumentFragment classe. Em muitos casos, no entanto, o XmlDocumentFragment conceito pode ser manipulado pelo resultado de uma consulta digitada como IEnumerable<T> de XNode, ou IEnumerable<T> de XElement.

Suporte para XPathNavigator

LINQ to XML fornece suporte para XPathNavigator através de métodos de extensão no System.Xml.XPath namespace. Para obter mais informações, veja System.Xml.XPath.Extensions.

Suporte para espaço em branco e recuo

LINQ to XML lida com espaço em branco de forma mais simples do que o DOM.

Um cenário comum é ler XML recuado, criar uma árvore XML na memória sem nós de texto de espaço em branco (ou seja, não preservar espaço em branco), fazer algumas operações no XML e, em seguida, salvar o XML com recuo. Quando você serializa o XML com formatação, apenas espaço em branco significativo na árvore XML é preservado. Este é o comportamento padrão para LINQ to XML.

Outro cenário comum é ler e modificar XML que já foi intencionalmente recuado. Talvez você não queira alterar esse recuo de forma alguma. No LINQ to XML, você pode fazer isso ao:

  • Preservando espaço em branco ao carregar ou analisar o XML.
  • Desativando a formatação quando você serializa o XML.

O LINQ to XML armazena espaço em branco como um XText nó, em vez de ter um tipo de nó especializado Whitespace , como faz o DOM.

Suporte para anotações

Os elementos LINQ to XML suportam um conjunto extensível de anotações. Isso é útil para rastrear informações diversas sobre um elemento, como informações de esquema, informações sobre se o elemento está vinculado a uma interface do usuário ou qualquer outro tipo de informação específica do aplicativo. Para obter mais informações, consulte Anotações LINQ to XML.

Suporte para informações de esquema

LINQ to XML fornece suporte para validação XSD por meio de System.Xml.Schema métodos de extensão no namespace. Você pode validar se uma árvore XML está em conformidade com um XSD. Você pode preencher a árvore XML com o conjunto de informações de validação pós-esquema (PSVI). Para obter mais informações, consulte Como validar usando XSD e Extensions.

Consulte também