Úpravy stromu XML v paměti vs. funkční konstrukce (LINQ to XML)

Úprava stromu XML je tradiční přístup ke změně tvaru dokumentu XML. Typická aplikace načte dokument do úložiště dat, jako je DOM nebo LINQ to XML; používá programovací rozhraní k vložení nebo odstranění uzlů nebo ke změně jejich obsahu; a pak soubor XML uloží do souboru nebo ho přenese přes síť.

LINQ to XML umožňuje jiný přístup, který je užitečný v mnoha scénářích: funkční konstrukce. Funkční konstrukce zpracovává úpravy dat jako problém transformace, nikoli jako podrobnou manipulaci s úložištěm dat. Pokud můžete data efektivně reprezentovat a transformovat je z jednoho formuláře do druhého, výsledek je stejný, jako kdybyste si vzali jedno úložiště dat a manipulovali s nimi nějakým způsobem, aby převzal jiný tvar. Klíčem k funkční konstrukci je předání výsledků dotazů XDocument a XElement konstruktorům.

V mnoha případech můžete za zlomek času napsat transformační kód, který by trvalo manipulovat s úložištěm dat, a výsledný kód je robustnější a snadněji se udržuje. V těchto případech, i když transformační přístup může mít vyšší výpočetní výkon, je efektivnější způsob, jak upravovat data. Pokud je vývojář obeznámen s funkčním přístupem, výsledný kód je v mnoha případech srozumitelnější a je snadné najít kód, který upravuje každou část stromu.

Přístup, ve kterém upravujete zavedený strom XML, je pro mnoho programátorů DOM známější, zatímco kód napsaný pomocí funkčního přístupu může vypadat pro vývojáře, který zatím tento přístup nezná. Pokud potřebujete pouze provést malou úpravu velkého stromu XML, bude přístup, ve kterém upravíte strom v mnoha případech, trvat méně času procesoru.

Tento článek obsahuje příklady obou přístupů. Předpokládejme, že chcete upravit následující jednoduchý dokument XML tak, aby se atributy staly elementy:

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

První z následujících příkladů používá tradiční místní přístup k úpravám a druhý používá funkční stavební přístup.

Příklad: Transformace atributů na prvky pomocí tradičního místního přístupu

Můžete napsat nějaký procedurální kód pro vytvoření prvků z atributů a pak odstranit atributy následujícím způsobem:

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)

Tento příklad vytvoří následující výstup:

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

Příklad: Transformace atributů na prvky pomocí přístupu k funkční konstrukci

Naproti tomu funkční přístup se skládá z kódu pro vytvoření nového stromu, výběru a výběru prvků a atributů ze zdrojového stromu a jejich transformace podle potřeby, jak jsou přidány do nového stromu.

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)

Tento příklad vypíše stejný kód XML jako první příklad. Všimněte si však, že ve funkčním přístupu můžete ve skutečnosti zobrazit výslednou strukturu nového XML. Můžete vidět vytvoření elementu Root , kód, který načte Child1 prvek ze zdrojového stromu, a kód, který transformuje atributy ze zdrojového stromu na prvky v novém stromu.

Funkční příklad v tomto případě není kratší ani jednodušší než první příklad. Pokud ale máte mnoho změn ve stromu XML, procedurální přístup se stane poměrně složitý a poněkud obtěžuje. Naproti tomu při použití funkčního přístupu stále vytváříte požadovaný KÓD XML, vkládejte dotazy a výrazy podle potřeby, abyste získali požadovaný obsah. Funkční přístup poskytuje kód, který se snadněji udržuje.

Všimněte si, že v tomto případě by funkční přístup pravděpodobně nedělal úplně stejně jako přístup pro manipulaci se stromy. Hlavním problémem je, že funkční přístup vytváří krátkodobé objekty. Kompromis je však účinný, pokud použití funkčního přístupu umožňuje větší produktivitu programátorů.

Toto je velmi jednoduchý příklad, ale slouží k zobrazení rozdílu v filozofie mezi dvěma přístupy. Funkční přístup přináší vyšší produktivitu pro transformaci větších dokumentů XML.