天天看點

linq to xml詳解

1、LINQ to XML類

linq to xml詳解

以下的代碼示範了如何使用LINQ to XML來快速建立一個xml:

隐藏行号 複制代碼 ? 建立 XML

  1. public static void CreateDocument()
          
  2. {
          
  3. string path = @"d:\website";
          
  4. XDocument xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
          
  5. new XElement("Root", "root"));
          
  6. xdoc.Save(path);
          
  7. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>      
<Root>root</Root>      

2、XElement類

XElement 類是 LINQ to XML 中的基礎類之一。 它表示一個 XML 元素。 可以使用該類建立元素;更改元素内容;添加、更改或删除子元素;向元素中添加屬性;或以文本格式序列化元素内容。 還可以與 System.Xml 中的其他類(例如 XmlReader、XmlWriter 和 XslCompiledTransform)進行互操作。

使用LINQ to XML建立xml文檔有很多種方式,具體使用哪種方法要根據實際需要。而建立xml文檔最簡單、最常見的方式是使用XElement類。以下的代碼示範了如何使用XElement類建立一個xml文檔:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void CreateCategories()
          
  2. {
          
  3. string path = @"d:\website";
          
  4. XElement root = new XElement("Categories",
          
  5. new XElement("Category",
          
  6. new XElement("CategoryID", Guid.NewGuid()),
          
  7. new XElement("CategoryName", "Beverages")
          
  8. ),
          
  9. new XElement("Category",
          
  10. new XElement("CategoryID", Guid.NewGuid()),
          
  11. new XElement("CategoryName", "Condiments")
          
  12. ),
          
  13. new XElement("Category",
          
  14. new XElement("CategoryID", Guid.NewGuid()),
          
  15. new XElement("CategoryName", "Confections")
          
  16. )
          
  17. );
          
  18. root.Save(path);
          
  19. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<Categories>      
<Category>      
<CategoryID>57485174-46fc-4e8c-8d98-d25b53d504a1</CategoryID>      
<CategoryName>Beverages</CategoryName>      
</Category>      
<Category>      
<CategoryID>1474dde1-8014-48f7-b093-b47ca5d5b770</CategoryID>      
<CategoryName>Condiments</CategoryName>      
</Category>      
<Category>      
<CategoryID>364224e0-e002-4939-90fc-0fd93e0cf35b</CategoryID>      
<CategoryName>Confections</CategoryName>      
</Category>      
</Categories>      

XElement類包含了許多方法,這些方法使得處理xml變得輕而易舉。有關這些方法請參照MSDN。

其中,Save、CreateReader、ToString和WriteTo方法是比較常用的三個方法:

linq to xml詳解

3、XAttribute類

XAttribute類用來處理元素的屬性,屬性是與元素相關聯的“名稱-值”對,每個元素中不能有名稱重複的屬性。使用XAttribute類與使用XElement類的操作十分相似,下面的示例示範了如何在建立xml樹時為其添加一個屬性:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static XElement CreateCategoriesByXAttribute()
          
  2. {
          
  3. XElement root = new XElement("Categories",
          
  4. new XElement("Category",
          
  5. new XAttribute("CategoryID", Guid.NewGuid()),
          
  6. new XElement("CategoryName", "Beverages")
          
  7. ),
          
  8. new XElement("Category",
          
  9. new XAttribute("CategoryID", Guid.NewGuid()),
          
  10. new XElement("CategoryName", "Condiments")
          
  11. ),
          
  12. new XElement("Category",
          
  13. new XAttribute("CategoryID", Guid.NewGuid()),
          
  14. new XElement("CategoryName", "Confections")
          
  15. )
          
  16. );
          
  17. root.Save(path);
          
  18. return root;
          
  19. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<Categories>      
<Category CategoryID="a6d5ef04-3f83-4e00-aeaf-52444add7570">      
<CategoryName>Beverages</CategoryName>      
</Category>      
<Category CategoryID="67a168d5-6b22-4d82-9bd4-67bec88c2ccb">      
<CategoryName>Condiments</CategoryName>      
</Category>      
<Category CategoryID="17398f4e-5ef1-48da-8a72-1c54371b8e76">      
<CategoryName>Confections</CategoryName>      
</Category>      
</Categories>      

XAttribute類的方法比較少,常用的三個是:

linq to xml詳解

以下的示例使用Remove來删除第一個元素的CategoryID屬性:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void RemoveAttribute()
          
  2. {
          
  3. XElement xdoc = CreateCategoriesByXAttribute();
          
  4. XAttribute xattr = xdoc.Element("Category").Attribute("CategoryID");
          
  5. xattr.Remove();
          
  6. xdoc.Save(path);
          
  7. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<Categories>      
<Category>      
<CategoryName>Beverages</CategoryName>      
</Category>      
<Category CategoryID="5c311c1e-ede5-41e5-93f7-5d8b1d7a0346">      
<CategoryName>Condiments</CategoryName>      
</Category>      
<Category CategoryID="bfde8db5-df84-4415-b297-cd04d8db9712">      
<CategoryName>Confections</CategoryName>      
</Category>      
</Categories>      

作為嘗試,試一試以下删除屬性的方法:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void RemoveAttributeByDoc()
          
  2. {
          
  3. XElement xdoc = CreateCategoriesByXAttribute();
          
  4. XAttribute xattr = xdoc.Attribute("CategoryID");
          
  5. xattr.Remove();
          
  6. xdoc.Save(path);
          
  7. }
          

運作該示例将會抛出一個空引用異常,因為元素Categories沒有一個叫做CategoryID的屬性。

4、XDocument類

XDocument類提供了處理xml文檔的方法,包括聲明、注釋和處理指令。一個XDocument對象可以包含以下内容:

linq to xml詳解

下面的示例建立了一個簡單的xml文檔,它包含幾個元素和一個屬性,以及一個處理指令和一些注釋:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void CreateXDocument()
          
  2. {
          
  3. XDocument xdoc = new XDocument(
          
  4. new XProcessingInstruction("xml-stylesheet", "title='EmpInfo'"),
          
  5. new XComment("some comments"),
          
  6. new XElement("Root",
          
  7. new XElement("Employees",
          
  8. new XElement("Employee",
          
  9. new XAttribute("id", "1"),
          
  10. new XElement("Name", "Scott Klein"),
          
  11. new XElement("Title", "Geek"),
          
  12. new XElement("HireDate", "02/05/2007"),
          
  13. new XElement("Gender", "M")
          
  14. )
          
  15. )
          
  16. ),
          
  17. new XComment("more comments")
          
  18. );
          
  19. xdoc.Save(path);
          
  20. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<?xml-stylesheet title='EmpInfo'?>      
<!--some comments-->      
<Root>      
<Employees>      
<Employee id="1">      
<Name>Scott Klein</Name>      
<Title>Geek</Title>      
<HireDate>02/05/2007</HireDate>      
<Gender>M</Gender>      
</Employee>      
</Employees>      
</Root>      
<!--more comments-->      

XDocument類包含多個與XElement類相同的方法,具體内容可以參閱MSDN。需要注意的是,處理節點和元素的大部分功能都可以通過XElement獲得,隻有當絕對需要文檔層次的處理能力,以及需要通路注釋、處理指令和聲明時,才有使用XDocument類的必要。

建立了xml文檔後,可以使用NodesAfterSelf方法傳回指定的XElement元素之後的所有同級元素。需要注意的是,此方法隻包括傳回集合中的同級元素,而不包括子代。此方法使用延遲執行。以下代碼示範了這一過程:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void NodesAfterSelf()
          
  2. {
          
  3. XElement root = new XElement("Categories",
          
  4. new XElement("Category",
          
  5. new XElement("CategoryID", Guid.NewGuid()),
          
  6. new XElement("CategoryName", "食品"),
          
  7. new XElement("Description", "可以吃的東西")
          
  8. )
          
  9. );
          
  10. foreach (var item in root.Element("Category").Element("CategoryID").NodesAfterSelf())
          
  11. {
          
  12. Console.WriteLine((item as XElement).Value);
          
  13. }
          
  14. }
          

二、LINQ to XML程式設計概念

本節将介紹LINQ to XML程式設計的相關概念,例如如何加載xml、建立全新xml、操縱xml的資訊以及周遊xml文檔。

1、加載已有的xml

使用LINQ to XML加載xml可以從多種資料源獲得,例如字元串、XmlReader、TextReader或檔案。

下面的示例示範了如何從檔案中加載xml:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void LoadFromFile()
          
  2. {
          
  3. XElement root = XElement.Load(path);
          
  4. Console.WriteLine(root.ToString());
          
  5. }
          

也可以使用Parse方法從一個字元串加載xml:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void LoadFromString()
          
  2. {
          
  3. ");
          
  4. Console.WriteLine(root.ToString());
          
  5. }
          

2、儲存xml

在前面的示例中曾多次調用XElement對象的Save方法來儲存xml文檔,在這裡就不冗述了。

3、建立xml

在前面的示例中曾多次調用XElement對象的構造函數來建立xml文檔,在這裡就不冗述了。需要說明的是,在使用LINQ to XML建立xml文檔時,會有代碼縮進,這使代碼的可讀性大大加強。

4、周遊xml

使用LINQ to XML在xml樹中周遊xml是相當簡單的。隻需要使用XElement和XAttribute類中所提供的方法。Elements和Element方法提供了定位到某個或某些元素的方式。下面的示例示範了如何周遊xml樹,并擷取指定元素的方式:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void Enum()
          
  2. {
          
  3. XElement root = new XElement("Categories");
          
  4. using (NorthwindDataContext db = new NorthwindDataContext())
          
  5. {
          
  6. root.Add(
          
  7. db.Categories
          
  8. .Select
          
  9. (
          
  10. (
          
  11. , new XElement("CategoryName", c.CategoryName)
          
  12. )
          
  13. )
          
  14. );
          
  15. }
          
  16. foreach (var item in root.Elements("Category"))
          
  17. {
          
  18. Console.WriteLine(item.Element("CategoryName").Value);
          
  19. }
          
  20. }
          

上述代碼運作的結果為:

linq to xml詳解

是不是很簡單呢?Nodes()、Elements()、Element(name)和Elements(name)方法為xml樹的導航提供了基本功能。

5、操縱xml

LINQ to XML一個重要的特性是能夠友善地修改xml樹,如添加、删除、更新和複制xml文檔的内容。

I.插入

使用XNode類的插入方法可以友善地向xml樹添加内容:

linq to xml詳解

在下面的示例中,使用AddAfterSelf方法向現有xml中添加一個新節點:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void AddAfterSelf()
          
  2. {
          
  3. ");
          
  4. XElement xele = root.Element("Category").Element("CategoryName");
          
  5. xele.AddAfterSelf(new XElement("AddDate", DateTime.Now));
          
  6. root.Save(path);
          
  7. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<Categories>      
<Category>      
<CategoryID>1</CategoryID>      
<CategoryName>Beverages</CategoryName>      
<AddDate>2010-01-31T03:08:51.813736+08:00</AddDate>      
<Description>Soft drinks, coffees, teas, beers, and ales</Description>      
</Category>      
</Categories>      

當需要添加一個元素到指定節點之前時,可以使用AddBeforeSelf方法。

II.更新

在LINQ to XML中更新xml内容可以使用以下幾種方法:

linq to xml詳解

在下面的示例中使用了ReplaceWith與SetElementValue方法對xml進行了更新操作:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void Update()
          
  2. {
          
  3. ");
          
  4. root.Element("Category").Element("CategoryID").ReplaceWith(new XElement("ID", "2"));
          
  5. root.Element("Category").SetElementValue("CategoryName", "test data");
          
  6. root.Save(path);
          
  7. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<Categories>      
<Category>      
<ID>2</ID>      
<CategoryName>test data</CategoryName>      
<Description>Soft drinks, coffees, teas, beers, and ales</Description>      
</Category>      
</Categories>      

III.删除

可以使用Remove(XElement)與RemoveAll方法來删除xml。

在下面的示例中,使用了RemoveAll方法:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. }
          
  2. public static void Remove()
          
  3. {
          
  4. string path = @"d:\";
          
  5. ");
          
  6. root.RemoveAll();
          
  7. root.Save(path);
          
  8. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<Categories />      

在下面的示例中,使用了Remove方法删除了xml的Description元素:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void Remove()
          
  2. {
          
  3. ");
          
  4. root.Element("Category").Element("Description").Remove();
          
  5. root.Save(path);
          
  6. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<Categories>      
<Category>      
<CategoryID>1</CategoryID>      
<CategoryName>Beverages</CategoryName>      
</Category>      
</Categories>      

6、處理屬性

I.添加

LINQ to XML添加屬性與添加元素師類似的,可以使用構造函數或者Add方法來添加屬性:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void AddAttribute()
          
  2. {
          
  3. XElement root = new XElement("Categories",
          
  4. new XElement("Category",
          
  5. new XAttribute("CategoryID", "1"),
          
  6. new XElement("CategoryName", "Beverages"),
          
  7. new XElement("Description", "Soft drinks, coffees, teas, beers, and ales")
          
  8. )
          
  9. );
          
  10. root.Element("Category").Add(new XAttribute("AddDate", DateTime.Now.ToShortDateString()));
          
  11. root.Save(path);
          
  12. }
          

運作該示例将會得到一個xml檔案,其内容為:

<?xml version="1.0" encoding="utf-8"?>      
<Categories>      
<Category CategoryID="1" AddDate="2010-01-31">      
<CategoryName>Beverages</CategoryName>      
<Description>Soft drinks, coffees, teas, beers, and ales</Description>      
</Category>      
</Categories>      

II.檢索

檢索屬性可以使用Attribute(name)方法:

顯示行号 複制代碼 ? 這是一段程式代碼。

  1. public static void SelectAttribute()
          
  2. {
          
  3. XElement root = new XElement("Categories",
          
  4. new XElement("Category",
          
  5. new XAttribute("CategoryID", "1"),
          
  6. new XElement("CategoryName", "Beverages"),
          
  7. new XElement("Description", "Soft drinks, coffees, teas, beers, and ales")
          
  8. )
          
  9. );
          
  10. XAttribute xattr = root.Element("Category").Attribute("CategoryID");
          
  11. Console.WriteLine(xattr.Name);
          
  12. Console.WriteLine(xattr.Value);
          
  13. }
          

上述代碼的運作結果為:

CategoryID

1

本文總結

本文介紹了LINQ to XML的程式設計基礎,即System.Xml.Linq命名空間中的多個LINQ to XML類,這些類都是LINQ to XML的支援類,它們使得處理xml比使用其他的xml工具容易得多。在本文中,着重介紹的是XElement、XAttribute和XDocument。