Minnesintern XML-trädändring jämfört med funktionell konstruktion (LINQ till XML)

Att ändra ett XML-träd på plats är en traditionell metod för att ändra formen på ett XML-dokument. Ett typiskt program läser in ett dokument i ett datalager som DOM eller LINQ till XML. använder ett programmeringsgränssnitt för att infoga eller ta bort noder eller ändra deras innehåll. och sparar sedan XML-koden i en fil eller överför den via ett nätverk.

LINQ till XML möjliggör en annan metod som är användbar i många scenarier: funktionell konstruktion. Funktionell konstruktion behandlar ändring av data som ett omvandlingsproblem snarare än som detaljerad manipulering av ett datalager. Om du kan ta en representation av data och transformera dem effektivt från ett formulär till ett annat, blir resultatet detsamma som om du tog ett datalager och manipulerade det på något sätt för att ta en annan form. En nyckel till den funktionella konstruktionsmetoden är att skicka resultatet av frågor till XDocument och XElement konstruktörer.

I många fall kan du skriva transformeringskoden på en bråkdel av den tid det skulle ta att manipulera datalagret, och den resulterande koden är mer robust och enklare att underhålla. I dessa fall, även om den transformerande metoden kan ta mer bearbetningskraft, är det ett effektivare sätt att ändra data. Om en utvecklare är bekant med den funktionella metoden är den resulterande koden i många fall lättare att förstå, och det är lätt att hitta koden som ändrar varje del av trädet.

Metoden där du ändrar ett XML-träd på plats är mer bekant för många DOM-programmerare, medan kod som skrivs med hjälp av den funktionella metoden kan se obekant ut för en utvecklare som ännu inte förstår den metoden. Om du bara behöver göra en liten ändring av ett stort XML-träd tar metoden där du ändrar ett träd på plats i många fall mindre CPU-tid.

Den här artikeln innehåller exempel på båda metoderna. Anta att du vill ändra följande enkla XML-dokument så att attributen blir element:

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

Det första av följande exempel använder den traditionella metoden för ändring på plats, och det andra använder den funktionella konstruktionsmetoden.

Exempel: Omvandla attribut till element med den traditionella metoden direkt på plats

Du kan skriva lite procedurkod för att skapa element från attributen och sedan ta bort attributen på följande sätt:

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)

Det här exemplet genererar följande utdata:

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

Exempel: Omvandla attribut till element med den funktionella konstruktionsmetoden

Däremot består en funktionell metod av kod för att bilda ett nytt träd, välja och välja element och attribut från källträdet och transformera dem efter behov när de läggs till i det nya trädet.

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)

I det här exemplet matas samma XML ut som i det första exemplet. Observera dock att du faktiskt kan se den resulterande strukturen för den nya XML-koden i funktionsmetoden. Du kan se skapandet av elementet Root , koden som hämtar elementet Child1 från källträdet och koden som transformerar attributen från källträdet till element i det nya trädet.

Det funktionella exemplet i det här fallet är varken kortare eller enklare än det första exemplet. Men om du har många ändringar att göra i ett XML-träd, blir tillvägagångssättet ganska komplext och något svårbegripligt. När du använder den funktionella metoden bildar du däremot bara önskad XML, bäddar in frågor och uttryck efter behov för att hämta önskat innehåll. Den funktionella metoden ger kod som är enklare att underhålla.

Observera att den funktionella metoden i det här fallet förmodligen inte skulle fungera lika bra som metoden för trädmanipulering. Huvudproblemet är att den funktionella metoden skapar fler kortlivade objekt. Kompromissen är dock effektiv om man använder den funktionella metoden för att öka programmerarens produktivitet.

Detta är ett mycket enkelt exempel, men det tjänar till att visa skillnaden i filosofi mellan de två metoderna. Den funktionella metoden ger större produktivitetsvinster vid transformering av större XML-dokument.