程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> ASP.NET基礎 >> LINQ to XML的編程基礎

LINQ to XML的編程基礎

編輯:ASP.NET基礎
一、LINQ to XML 編程基礎
1、LINQ to XML類
System.Xml.Linq命名空間含有19個類,下表列出了它們的名稱及其描述:

描述

XAttribute

表示一個 XML 屬性

XCData

表示一個 CDATA 文本節點

XComment

表示一個 XML 注釋

XContainer

適用於可能具有子節點的所有節點的抽象基類

XDeclaration

表示一個 XML 聲明

XDocument

表示一個 XML 文檔

XDocumentType

表示一個 XML 文檔類型定義 (DTD)

XElement

表示一個 XML 元素

XName

表示一個XML元素或屬性的名稱

XNamespace

表示一個XML的命名空間

XNode

一個抽象類,它表示 XML 樹的節點

XNodeDocumentOrderComparer

提供用於比較節點的文檔順序的功能

XNodeEqualityComparer

提供用於比較節點的值是否相等的功能

XObject

XNode 和 XAttribute 的抽象基類

XObjectChange

XObject引發事件時的事件類型

XObjectChangeEventArgs

為 Changing 和 Changed 事件提供數據

XProcessingInstruction

表示一個 XML 處理指令

XText

表示一個文本節點

以下的代碼演示了如何使用LINQ to XML來快速創建一個xml:
復制代碼 代碼如下:
public static void CreateDocument()
{
XDocument xdoc = new XDocument
(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("Root","root")
);
xdoc.Save(path);
}

運行該示例將會得到一個xml文件,其內容為:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>root</Root>
可以看出微軟在LINQ上投入了很大的精力,使我們在編程時感覺到很舒服。下面將詳細介紹處理XML時使用最多的三個類:XElement、XAttribute和XDocument。如果掌握了這些類,使用LINQ to XML時將會感到很順手。
2、XElement類
XElement 類是 LINQ to XML 中的基礎類之一。 它表示一個 XML 元素。 可以使用該類創建元素;更改元素內容;添加、更改或刪除子元素;向元素中添加屬性;或以文本格式序列化元素內容。 還可以與 System.Xml 中的其他類(例如 XmlReader、XmlWriter 和 XslCompiledTransform)進行互操作。
使用LINQ to XML創建xml文檔有很多種方式,具體使用哪種方法要根據實際需要。而創建xml文檔最簡單、最常見的方式是使用XElement類。以下的代碼演示了如何使用XElement類創建一個xml文檔:
復制代碼 代碼如下:
public static void CreateCategories()
{
XElement root = new XElement("Categories",
new XElement("Category",
new XElement("CategoryID", Guid.NewGuid()),
new XElement("CategoryName", "Beverages")
),
new XElement("Category",
new XElement("CategoryID", Guid.NewGuid()),
new XElement("CategoryName", "Condiments")
),
new XElement("Category",
new XElement("CategoryID", Guid.NewGuid()),
new XElement("CategoryName", "Confections")
)
);
root.Save(path);
}

運行該示例將會得到一個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>

LINQ to XML的強大之處還在於它可以使用LINQ to SQL或者LINQ to Object獲取數據源,然後填充到xml樹。以下的示例從Northwind數據庫中讀取Categories、Products表中的數據來創建包含產品類別,以及每個類別下所有產品的xml文件:
復制代碼 代碼如下:
public static void CreateCategoriesFromDatabase()
{
using (NorthwindDataContext db = new NorthwindDataContext())
{
XElement root = new XElement("Categories",
db.Categories
.Select
(
c => new XElement
(
"Category"
, new XElement("CategoryID", c.CategoryID)
, new XElement("CategoryName", c.CategoryName)
, new XElement
(
"Products"
, c.Products
.Select
(
p => new XElement
(
"Product"
, new XElement("ProductName", p.ProductName)
)
)
.Take(2)
)
)
)
.Take(3)
);
root.Save(path);
}
}

運行該示例將會得到一個xml文件,其內容為:
復制代碼 代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<Categories>
<Category>
<CategoryID>1</CategoryID>
<CategoryName>Beverages</CategoryName>
<Products>
<Product>
<ProductName>Chai</ProductName>
</Product>
<Product>
<ProductName>Chang</ProductName>
</Product>
</Products>
</Category>
<Category>
<CategoryID>2</CategoryID>
<CategoryName>Condiments</CategoryName>
<Products>
<Product>
<ProductName>Aniseed Syrup</ProductName>
</Product>
<Product>
<ProductName>Chef Anton's Cajun Seasoning</ProductName>
</Product>
</Products>
</Category>
<Category>
<CategoryID>3</CategoryID>
<CategoryName>Confections</CategoryName>
<Products>
<Product>
<ProductName>Pavlova</ProductName>
</Product>
<Product>
<ProductName>Teatime Chocolate Biscuits</ProductName>
</Product>
</Products>
</Category>
</Categories>

XElement類包含了許多方法,這些方法使得處理xml變得輕而易舉。有關這些方法請參照MSDN。
其中,Save、CreateReader、ToString和WriteTo方法是比較常用的三個方法:

方法

參數

返回值

描述

CreateReader

System.Xml.XmlReader

創建此節點的 XmlReader

Save

System.String

void

將此元素序列化為文件

System.IO.TextWriter

void

將此元素序列化為 TextWriter

System.Xml.XmlWriter

void

將此元素序列化為 XmlWriter

System.String,

System.Xml.Linq.SaveOptions

void

將此元素序列化為文件,並可以選擇禁用格式設置

System.IO.TextWriter,

System.Xml.Linq.SaveOptions

void

將此元素序列化為 TextWriter,並可以選擇禁用格式設置

WriteTo

System.Xml.XmlWriter

void

將此元素寫入 XmlWriter

ToString

System.String

返回此節點的縮進 XML

System.Xml.Linq.SaveOptions

System.String

返回此節點的 XML,並可以選擇禁用格式設置

現在有很多使用XmlReader作為數據源的應用程序,使用XElement可以很方便地提供支持。
3、XAttribute類
XAttribute類用來處理元素的屬性,屬性是與元素相關聯的“名稱-值”對,每個元素中不能有名稱重復的屬性。使用XAttribute類與使用XElement類的操作十分相似,下面的示例演示了如何在創建xml樹時為其添加一個屬性:
復制代碼 代碼如下:
public static XElement CreateCategoriesByXAttribute()
{
XElement root = new XElement("Categories",
new XElement("Category",
new XAttribute("CategoryID", Guid.NewGuid()),
new XElement("CategoryName", "Beverages")
),
new XElement("Category",
new XAttribute("CategoryID", Guid.NewGuid()),
new XElement("CategoryName", "Condiments")
),
new XElement("Category",
new XAttribute("CategoryID", Guid.NewGuid()),
new XElement("CategoryName", "Confections")
)
);
root.Save(path);
return root;
}

運行該示例將會得到一個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類的方法比較少,常用的三個是:

方法

描述

AddAnnotation

為該屬性添加注解

Remove

刪除該屬性

SetValue

設定該屬性的值

以下的示例使用Remove來刪除第一個元素的CategoryID屬性:
復制代碼 代碼如下:
public static void RemoveAttribute()
{
XElement xdoc = CreateCategoriesByXAttribute();
XAttribute xattr = xdoc.Element("Category").Attribute("CategoryID");
xattr.Remove();
xdoc.Save(path);
}

運行該示例將會得到一個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>

作為嘗試,試一試以下刪除屬性的方法:
復制代碼 代碼如下:
public static void RemoveAttributeByDoc()
{
XElement xdoc = CreateCategoriesByXAttribute();
XAttribute xattr = xdoc.Attribute("CategoryID");
xattr.Remove();
xdoc.Save(path);
}

運行該示例將會拋出一個空引用異常,因為元素Categories沒有一個叫做CategoryID的屬性。
4、XDocument類
XDocument類提供了處理xml文檔的方法,包括聲明、注釋和處理指令。一個XDocument對象可以包含以下內容:

對象

個數

說明

XDeclaration

一個

用於指定xml聲明中的重要組成部分,如文檔編碼和版本等

XElement

一個

指定文檔的根元素

XDocumentType

一個

表示一個xml DTD

XComment

多個

Xml注釋。它不能是第一個參數,因為一個有效的xml文檔不能以注釋作為開始

XProcessingInstruction

多個

為處理xml的應用程序指定任何所需信息

下面的示例創建了一個簡單的xml文檔,它包含幾個元素和一個屬性,以及一個處理指令和一些注釋:
復制代碼 代碼如下:
public static void CreateXDocument()
{
XDocument xdoc = new XDocument(
new XProcessingInstruction("xml-stylesheet", "title='EmpInfo'"),
new XComment("some comments"),
new XElement("Root",
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", "1"),
new XElement("Name", "Scott Klein"),
new XElement("Title", "Geek"),
new XElement("HireDate", "02/05/2007"),
new XElement("Gender", "M")
)
)
),
new XComment("more comments")
);
xdoc.Save(path);
}

運行該示例將會得到一個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元素之後的所有同級元素。需要注意的是,此方法只包括返回集合中的同級元素,而不包括子代。此方法使用延遲執行。以下代碼演示了這一過程:
復制代碼 代碼如下:
public static void NodesAfterSelf()
{
XElement root = new XElement("Categories",
new XElement("Category",
new XElement("CategoryID", Guid.NewGuid()),
new XElement("CategoryName", "食品"),
new XElement("Description", "可以吃的東西")
)
);
foreach (var item in root.Element("Category").Element("CategoryID").NodesAfterSelf())
{
Console.WriteLine((item as XElement).Value);
}
}

執行的結果如下:

clip_image001

使用LINQ to XML中的類來處理xml十分簡單和高效,包括創建、查詢和操縱xml。
二、LINQ to XML編程概念
本節將介紹LINQ to XML編程的相關概念,例如如何加載xml、創建全新xml、操縱xml的信息以及遍歷xml文檔。
1、加載已有的xml
使用LINQ to XML加載xml可以從多種數據源獲得,例如字符串、XmlReader、TextReader或文件。
下面的示例演示了如何從文件中加載xml:
復制代碼 代碼如下:
public static void LoadFromFile()
{
XElement root = XElement.Load(path);
Console.WriteLine(root.ToString());
}

也可以使用Parse方法從一個字符串加載xml:
復制代碼 代碼如下:
public static void LoadFromString()
{
XElement root = XElement.Parse(@"
<Categories>
<Category>
<CategoryID>1</CategoryID>
<CategoryName>Beverages</CategoryName>
<Description>Soft drinks, coffees, teas, beers, and ales</Description>
</Category>
</Categories>
");
Console.WriteLine(root.ToString());
}

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樹,並獲取指定元素的方式:
復制代碼 代碼如下:
public static void Enum()
{
XElement root = new XElement("Categories");
using (NorthwindDataContext db = new NorthwindDataContext())
{
root.Add(
db.Categories
.Select
(
c => new XElement
(
"Category"
, new XElement("CategoryName", c.CategoryName)
)
)
);
}
foreach (var item in root.Elements("Category"))
{
Console.WriteLine(item.Element("CategoryName").Value);
}
}
}

上述代碼運行的結果為:

clip_image002

是不是很簡單呢?Nodes()、Elements()、Element(name)和Elements(name)方法為xml樹的導航提供了基本功能。
5、操縱xml
LINQ to XML一個重要的特性是能夠方便地修改xml樹,如添加、刪除、更新和復制xml文檔的內容。

I.插入
使用XNode類的插入方法可以方便地向xml樹添加內容:

方法

說明

AddAfterSelf

緊跟在此節點之後添加指定的內容

AddBeforeSelf

緊鄰此節點之前添加指定的內容

在下面的示例中,使用AddAfterSelf方法向現有xml中添加一個新節點:
復制代碼 代碼如下:
public static void AddAfterSelf()
{
XElement root = XElement.Parse(@"
<Categories>
<Category>
<CategoryID>1</CategoryID>
<CategoryName>Beverages</CategoryName>
<Description>Soft drinks, coffees, teas, beers, and ales</Description>
</Category>
</Categories>
");
XElement xele = root.Element("Category").Element("CategoryName");
xele.AddAfterSelf(new XElement("AddDate", DateTime.Now));
root.Save(path);
}

運行該示例將會得到一個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內容可以使用以下幾種方法:

方法

說明

ReplaceWith

用指定的內容來取代當前元素的內容

ReplaceAll

用指定的內容來取代當前元素的子節點及相關的屬性

ReplaceNodes

用指定的內容來取代文檔或當前元素的子節點

SetAttributeValue

設置屬性的值、添加屬性或移除屬性

SetElementValue

設置子元素的值、添加子元素或移除子元素

在下面的示例中使用了ReplaceWith與SetElementValue方法對xml進行了更新操作:
復制代碼 代碼如下:
public static void Update()
{
XElement root = XElement.Parse(@"
<Categories>
<Category>
<CategoryID>1</CategoryID>
<CategoryName>Beverages</CategoryName>
<Description>Soft drinks, coffees, teas, beers, and ales</Description>
</Category>
</Categories>
");
root.Element("Category").Element("CategoryID").ReplaceWith(new XElement("ID", "2"));
root.Element("Category").SetElementValue("CategoryName", "test data");
root.Save(path);
}

運行該示例將會得到一個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方法:
復制代碼 代碼如下:
public static void Remove()
{
XElement root = XElement.Parse(@"
<Categories>
<Category>
<CategoryID>1</CategoryID>
<CategoryName>Beverages</CategoryName>
<Description>Soft drinks, coffees, teas, beers, and ales</Description>
</Category>
</Categories>
");
root.RemoveAll();
root.Save(path);
}

運行該示例將會得到一個xml文件,其內容為:
<?xml version="1.0" encoding="utf-8"?>
<Categories />
在下面的示例中,使用了Remove方法刪除了xml的Description元素:
復制代碼 代碼如下:
public static void Remove()
{
XElement root = XElement.Parse(@"
<Categories>
<Category>
<CategoryID>1</CategoryID>
<CategoryName>Beverages</CategoryName>
<Description>Soft drinks, coffees, teas, beers, and ales</Description>
</Category>
</Categories>
");
root.Element("Category").Element("Description").Remove();
root.Save(path);
}

運行該示例將會得到一個xml文件,其內容為:
復制代碼 代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<Categories>
<Category>
<CategoryID>1</CategoryID>
<CategoryName>Beverages</CategoryName>
</Category>
</Categories>

6、處理屬性
I.添加
LINQ to XML添加屬性與添加元素師類似的,可以使用構造函數或者Add方法來添加屬性:
復制代碼 代碼如下:
public static void AddAttribute()
{
XElement root = new XElement("Categories",
new XElement("Category",
new XAttribute("CategoryID","1"),
new XElement("CategoryName","Beverages"),
new XElement("Description", "Soft drinks, coffees, teas, beers, and ales")
)
);
root.Element("Category").Add(new XAttribute("AddDate", DateTime.Now.ToShortDateString()));
root.Save(path);
}

運行該示例將會得到一個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)方法:
復制代碼 代碼如下:
public static void SelectAttribute()
{
XElement root = new XElement("Categories",
new XElement("Category",
new XAttribute("CategoryID", "1"),
new XElement("CategoryName", "Beverages"),
new XElement("Description", "Soft drinks, coffees, teas, beers, and ales")
)
);
XAttribute xattr = root.Element("Category").Attribute("CategoryID");
Console.WriteLine(xattr.Name);
Console.WriteLine(xattr.Value);
}

上述代碼的運行結果為:
CategoryID
1
III.刪除
刪除屬性的操作是調用XAttribute對象的Remove方法來完成的。
本文總結
本文介紹了LINQ to XML的編程基礎,即System.Xml.Linq命名空間中的多個LINQ to XML類,這些類都是LINQ to XML的支持類,它們使得處理xml比使用其他的xml工具容易得多。在本文中,著重介紹的是XElement、XAttribute和XDocument。
pdf版下載,更容易閱讀

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved