Compartilhar via


LINQ to XML e DOM

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

Novas maneiras de construir árvores XML

No DOM 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 da 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 dá suporte a uma abordagem alternativa, construção funcional, que mostra melhor a estrutura. Essa abordagem pode ser feita com os construtores XElement 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 indentar 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 é em elementos XML e talvez em atributos. No LINQ to XML, você pode trabalhar diretamente com elementos XML e atributos. Por exemplo, é possível 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.
  • Serializar objetos T:System.Xml.Linq.XElement em um arquivo ou em um fluxo.

Compare isso com o DOM W3C, no qual o documento XML é usado como um contêiner lógico para a árvore XML. No DOM, os 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 de nome 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 você quiser usar um elemento em vários documentos, deverá importar os nós entre documentos. LINQ to XML evita essa camada de complexidade.

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

Tratamento simplificado de nomes e namespaces

Lidar com nomes, namespaces e prefixos de namespace geralmente é uma parte complexa da programação XML. LINQ to XML simplifica nomes e namespaces eliminando o requisito de lidar com prefixos de namespace. Se você quiser controlar os prefixos do namespace, poderá. 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 forem necessários, ou utilizará namespaces padrão se não forem. Se os namespaces padrão forem usados, não haverá prefixos de namespace no documento resultante. Para obter mais informações, consulte a visão geral de Namespaces.

Outro problema com os 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 filhos para ele, perdendo a identidade do nó original. O LINQ to XML evita esse problema permitindo que você defina a propriedade XName em um nó.

Suporte a métodos estáticos 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 constructos DTD

LINQ to XML simplifica ainda mais a programação XML removendo o suporte para entidades e referências de entidade. O gerenciamento de entidades é complexo e raramente é usado. A remoção do 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 conceito de XmlDocumentFragment pode ser tratado pelo resultado de uma consulta que é digitada como IEnumerable<T> de XNode ou IEnumerable<T> de XElement.

Suporte para XPathNavigator

O LINQ to XML dá suporte a XPathNavigator por meio de métodos de extensão no namespace System.Xml.XPath. Para obter mais informações, consulte System.Xml.XPath.Extensions.

Suporte para espaço em branco e indentação

LINQ to XML manipula o espaço em branco mais simplesmente do que o DOM.

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

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

  • Preservando o espaço em branco quando você carrega ou analisa o XML.
  • Desabilitando a formatação quando você serializa o XML.

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

Suporte para anotações

Os elementos LINQ to XML dão suporte a um conjunto extensível de anotações. Isso é útil para acompanhar informações diversas 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ção específica do aplicativo. Para mais informações, confira Anotações LINQ to XML.

Suporte para informações do esquema

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

Consulte também