記憶體內部 XML 樹狀結構修改與功能建構 (LINQ to XML)

就地修改 XML 樹狀結構是變更 XML 文件組織結構的傳統方式。 一般應用程式會將檔載入至 DOM 或LINQ to XML等資料存放區;使用程式設計介面來插入或刪除節點,或變更其內容;然後將 XML 儲存至檔案,或透過網路傳輸。

LINQ to XML可讓其他方法在許多案例中很有用:功能建構。 功能結構會將修改資料視為轉換的問題,而不是資料存放區的詳細管理。 如果您可以表示資料,並將其有效地從一個表單轉換到另一個表單,結果會與您取得一個資料存放區,然後以相同的方式管理該資料存放區取得其他組織結構相同。 功能結構方法的關鍵在於將查詢結果傳遞到 XDocumentXElement 建構函式。

在許多情況下,您可以在運算元據存放區所需的時間中撰寫轉換程式碼,而產生的程式碼更強固且更容易維護。 在這些情況下,即使轉換方法可以採用更多處理能力,但它是修改資料更有效率的方式。 如果開發人員熟悉功能方法,則在許多情況下產生的程式碼更容易瞭解,而且很容易找到修改樹狀結構每個部分的程式碼。

您就地修改 XML 樹狀結構的方法對許多 DOM 程式設計人員來說比較熟悉,而使用功能方法撰寫的程式碼可能看起來不熟悉尚未了解該方法的開發人員。 如果您必須針對大型 XML 樹狀結構進行小小的修改,您就地修改樹狀結構的方法在大部分的情況下,將會需要較少的 CPU 時間。

本文提供這兩種方法的範例。 假設您想要修改下列簡單的 XML 檔,讓屬性變成元素:

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

下列範例的第一個範例使用傳統的就地修改方法,第二個則使用功能建構方法。

範例:使用傳統就地方法將屬性轉換成元素

您可以撰寫特定的程序性程式碼以便從屬性建立項目,然後刪除該屬性,如下所示:

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)

這個範例會產生下列輸出:

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

範例:使用功能建構方法將屬性轉換成元素

相反地,功能方法包含程式碼來形成新的樹狀結構、從來源樹狀結構挑選及選擇元素和屬性,並在新增至新樹狀結構時視需要加以轉換。

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)

這個範例會與第一個範例輸出相同的 XML。 但是請注意,您實際上可以用功能性方法查看所產生的新 XML 結構。 您可以查看 Root 項目的建立、從來源樹狀結構提取 Child1 項目的程式碼,以及將屬性從來源樹狀結構轉換到新樹狀結構中的項目之程式碼。

在此案例中,功能範例不會比第一個範例短或更簡單。 不過,如果您對 XML 樹狀結構進行許多變更,則程式性方法會變得相當複雜且有點模糊。 相反地,使用功能性方法時,您仍然可以在適當地內嵌查詢和運算式,只形成所需的 XML,以便在所需的內容中提取。 功能性方法會產生容易維護的程式碼。

請注意,在這個情況下,功能性方法可能不會實際與樹狀結構管理方法一起執行。 主要問題是功能方法會建立更短期的物件。 不過,如果使用功能性方法能讓程式設計人員的產能更大,進行取捨是有效的方法。

這是非常簡單的範例,但是它有助於顯示兩種方法間的觀點差異。 功能性方法在轉換大型 XML 文件時,會產生較大的產能。