LINQ to XML vs. DOM
Esta seção descreve algumas das principais diferenças entre o LINQ to XML e a API de programação de XML predominante atual, o W3C Document Object Model (DOM).
Novas maneiras de criar árvores XML
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.
Por exemplo, veja a seguir uma maneira comum 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)
Este estilo de codificação não fornece visualmente muitas informações sobre a estrutura da árvore XML. O LINQ to XML dá suporte a esta abordagem para construir uma árvore XML, mas também dá suporte a uma abordagem alternativa, a construção funcional. A construção funcional usa os construtores XElement e de XAttribute para criar uma árvore XML.
Veja aqui como você poderia construir a mesma árvore XML usando a construção funcional LINQ to XML:
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")
)
)
);
Observe que o recuo do código para construir a árvore XML mostra a estrutura do XML subjacente.
No Visual Basic, o código para construir a árvore XML é ainda mais simples, pois ele usa um literal XML:
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>
Se você tiver um documento XML existente e quiser criar uma árvore XML a partir dele, abra o documento XML em um editor, copie o XML para a área de transferência, abra um módulo do Visual Basic no Visual Studio e cole o XML diretamente no editor de código do Visual Basic.
Para obter mais informações, consulte Criando árvores XML.
Trabalhando diretamente com Elementos XML
Quando você programa com XML, o foco principal é geralmente 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:
Criar elementos XML sem usar nenhum objeto de documento. Isso simplifica a programação quando você tem que trabalhar com partes de árvores XML.
Carregue objetos T:System.Xml.Linq.XElement diretamente de um arquivo XML.
Serialize objetos T:System.Xml.Linq.XElement para um arquivo ou fluxo.
Compare isso para o W3C DOM, 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 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. O LINQ to XML evitar essa camada de complexidade.
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.
Tratamento simplificado de nomes e namespaces
Tratar nomes, namespaces e prefixos de namespace é geralmente uma parte complexa da programação de XML. O LINQ to XML simplifica nomes e namespaces eliminando a necessidade de lidar com os prefixos de namespace. Se quiser, você pode controlar prefixos de namespace. Mas se 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 os serializará usando 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 Trabalhando com namespaces XML.
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 de método estático para carregar XML
O LINQ to XML permite que você carregue XML usando métodos estáticos, em vez dos 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 de suporte para construções de DTD
O LINQ to XML simplifica ainda mais a programação de XML removendo o suporte para entidades e referências a entidades. O gerenciamento de entidades é complexo e é raramente usado. Remover o suporte aumenta o desempenho e simplifica a interface de programação. Quando uma árvore do LINQ to XML é preenchida, todas as entidades de DTD são expandidas.
Suporte para fragmentos
O LINQ to XML não fornece um equivalente para a classe XmlDocumentFragment. Em muitos casos, no entanto, o conceito de XmlDocumentFragment pode ser tratado pelo resultado de uma consulta que é digitada como IEnumerable de XNode ou IEnumerable de XElement.
Suporte para XPathNavigator
O LINQ to XML fornece suporte para XPathNavigator por meio de métodos de extensão no namespace System.Xml.XPath. Para obter mais informações, consulte Extensions.
Suporte para espaço em branco e recuo
O LINQ to XML trata espaços em branco de maneira mais simples que o DOM.
Um cenário comum é ler o XML recuado, criar uma árvore XML na memória sem nenhum nó de texto de espaço em branco (isto é, não preservar espaço em branco), executar algumas operações no XML e, em seguida, salvar o XML com recuo. Quando você serializa o XML com formatação, somente os espaços em branco significativos na árvore XML são preservados. Este é o comportamento padrão para LINQ to XML.
Outro cenário comum é ler e modificar XML que já foi recuado intencionalmente. Você pode não querer modificar este recuo de nenhuma forma. No LINQ to XML, você pode fazer isso preservando o espaço em branco ao carregar ou analisar o XML e desabilitando a formatação ao serializar 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, como o DOM.
Suporte para anotações
Os elementos do LINQ to XML dão suporte a um conjunto extensível de anotações. Isso é útil para controlar 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. Para obter mais informações, consulte LINQ às anotações XML.
Suporte para informações do esquema
O LINQ to XML fornece suporte para validação de XSD por meio de métodos de extensão no namespace System.Xml.Schema. Você pode validar que uma árvore XML está em conformidade com XSD. Você pode preencher a árvore XML com o PSVI (post-schema-validation infoset). Para obter mais informações, consulte Como validar usando XSD (LINQ to XML) e Extensions.