Partilhar via


Modificação da árvore XML na memória vs. construção funcional (LINQ to XML)

Modificar uma árvore XML no local é uma abordagem tradicional para alterar a forma de um documento XML. Um aplicativo típico carrega um documento em um armazenamento de dados, como DOM ou LINQ to XML; usa uma interface de programação para inserir ou excluir nós, ou alterar seu conteúdo; e, em seguida, guarda o XML num ficheiro ou transmite-o através de uma rede.

O LINQ to XML permite outra abordagem que é útil em muitos cenários: a construção funcional. A construção funcional trata a modificação de dados como um problema de transformação, e não como manipulação detalhada de um armazenamento de dados. Se você puder pegar uma representação de dados e transformá-la de forma eficiente de um formulário para outro, o resultado será o mesmo que se você pegasse um armazenamento de dados e o manipulasse de alguma forma para assumir outra forma. Uma chave para a abordagem de construção funcional é passar os resultados das consultas para XDocument e XElement construtores.

Em muitos casos, você pode escrever o código transformacional em uma fração do tempo que levaria para manipular o armazenamento de dados, e o código resultante é mais robusto e fácil de manter. Nesses casos, embora a abordagem transformacional possa ter mais poder de processamento, é uma maneira mais eficaz de modificar dados. Se um desenvolvedor estiver familiarizado com a abordagem funcional, o código resultante em muitos casos é mais fácil de entender e é fácil encontrar o código que modifica cada parte da árvore.

A abordagem em que você modifica uma árvore XML no local é mais familiar para muitos programadores DOM, enquanto o código escrito usando a abordagem funcional pode parecer desconhecido para um desenvolvedor que ainda não entende essa abordagem. Se você tiver que fazer apenas uma pequena modificação em uma árvore XML grande, a abordagem em que você modifica uma árvore no local em muitos casos levará menos tempo de CPU.

Este artigo fornece exemplos de ambas as abordagens. Suponha que você queira modificar o seguinte documento XML simples para que os atributos se tornem elementos:

<?xml version="1.0" encoding="utf-8" ?>
<Root Data1="123" Data2="456">
  <Child1>Content</Child1>
</Root>

O primeiro dos exemplos a seguir usa a abordagem tradicional de modificação in-loco e o segundo usa a abordagem de construção funcional.

Exemplo: Transformar atributos em elementos com a abordagem tradicional in-loco

Você pode escrever algum código de procedimento para criar elementos a partir dos atributos e, em seguida, excluir os atributos, da seguinte maneira:

XElement root = XElement.Load("Data.xml");
foreach (XAttribute att in root.Attributes()) {
    root.Add(new XElement(att.Name, (string)att));
}
root.Attributes().Remove();
Console.WriteLine(root);
Dim root As XElement = XElement.Load("Data.xml")
For Each att As XAttribute In root.Attributes()
    root.Add(New XElement(att.Name, att.Value))
Next
root.Attributes().Remove()
Console.WriteLine(root)

Este exemplo produz a seguinte saída:

<Root>
  <Child1>Content</Child1>
  <Data1>123</Data1>
  <Data2>456</Data2>
</Root>

Exemplo: Transformar atributos em elementos com a abordagem de construção funcional

Por outro lado, uma abordagem funcional consiste em código para formar uma nova árvore, selecionando e escolhendo elementos e atributos da árvore de origem e transformando-os conforme apropriado à medida que são adicionados à nova árvore.

XElement root = XElement.Load("Data.xml");
XElement newTree = new XElement("Root",
    root.Element("Child1"),
    from att in root.Attributes()
    select new XElement(att.Name, (string)att)
);
Console.WriteLine(newTree);
Dim root As XElement = XElement.Load("Data.xml")
Dim newTree As XElement = _
    <Root>
        <%= root.<Child1> %>
        <%= From att In root.Attributes() _
            Select New XElement(att.Name, att.Value) %>
    </Root>
Console.WriteLine(newTree)

Este exemplo gera o mesmo XML do primeiro exemplo. No entanto, observe que você pode realmente ver a estrutura resultante do novo XML na abordagem funcional. Você pode ver a Root criação do elemento , o código que extrai o Child1 elemento da árvore de origem e o código que transforma os atributos da árvore de origem em elementos na nova árvore.

O exemplo funcional, neste caso, não é nem mais curto nem mais simples do que o primeiro exemplo. No entanto, se você tiver muitas alterações a fazer em uma árvore XML, a abordagem processual se tornará bastante complexa e um tanto obtusa. Por outro lado, ao usar a abordagem funcional, você ainda apenas forma o XML desejado, incorporando consultas e expressões conforme apropriado, para obter o conteúdo desejado. A abordagem funcional produz um código mais fácil de manter.

Observe que, neste caso, a abordagem funcional provavelmente não funcionaria tão bem quanto a abordagem de manipulação de árvores. A principal questão é que a abordagem funcional cria mais objetos de curta duração. No entanto, o tradeoff é eficaz se o uso da abordagem funcional permitir uma maior produtividade do programador.

Este é um exemplo muito simples, mas serve para mostrar a diferença de filosofia entre as duas abordagens. A abordagem funcional produz maiores ganhos de produtividade para transformar documentos XML maiores.