.XML
可擴展標記語言 (Extensible Markup Language), 標記 (markup) 是關鍵部分,是標準通用標記語言 (Standard Generalized Markup Language,SGML) 的子集,一種簡單的存儲和提取數據的文本格式,允許用戶對自己的標記語言進行定義的源語言。XML數據是分層組織的,組織數據的結構化方式,易於使用和擴展的標記語言,主要用於傳輸和存儲數據,是各種應用程序之間進行數據傳輸的常用工具,而HTML主要用於顯示數據。.XML 文件由內容和標記組成,具體地:
- 文檔類型定義 (Document Type Definition,DTD),規定文檔的邏輯結構;
- 可擴展的樣式語言(Extensible Style Language,XSL),規定XML文檔樣式;
- 可擴展鏈接語言 (Extensible Link Language,XLL),支持Web上已有的簡單鏈接;
XML方便有效地表示結構化數據,使用XML進行信息描述和數據交換已經成爲計算機軟件領域的標準技術模式。通過XML實現數據的標準化、結構化,解決了不同平臺、不同系統之間數據結構/模式的差異,使數據層在XML技術的支持下統一起來。
XML語法
XML文檔用XML聲明、XML名稱空間、XML元素和特性構建。聲明定義XML版本,名稱空間定義詞彙表,元素和特性 定義XML文檔的內容。
<?xml version="1.0" encoding="gb2312"?>
元素是XML文檔最重要的部分,包含文檔的實際數據,元素之間不允許交叉重疊。相較於HTML,XML沒有任何預定義的元素和結構。根元素是通過XmlDocument類的屬性DocumentElement獲得。主要的類:XDocument、XElement、XAttribute。
讀取方法
在程序中訪問並操作.XML文件一般有兩種模型,分別是使用文檔對象模型DOM和流模型。使用DOM的好處在於它允許編輯和更新XML文檔,可以隨機訪問文檔中的數據、可以使用XPath查詢,但是,DOM的缺點是需要一次性加載整個文檔到內存,對於大型文檔會造成資源問題。流模型很好的解決這個問題,因爲它對.XML文件的訪問採用流的概念,也就是說,任何時候內存中只有當前節點,但它是隻讀的、向前的,不能在文檔中執行向後導航操作。三種常用的讀取XML文件的方法:
- - - 使用 XmlDocument
- - - 使用 XmlTextReader
- - - 使用 Linq to Xml
以如下.XML文檔爲例進行說明:
<?xml version="1.0" encoding="gb2312">
<RootConfig>
<campaigns>
<campaign Year="2015">
<DictDatas Page="p1">
<Dict name="DeviceNo">
<item value="010">北京</item>
<item value="021">上海</item>
<item value="0536">濰坊</item>
<IsComboBox>Yes</IsComboBox>
</Dict>
</DictDatas>
</campaign>
<campaign Year="2016">
<DictDatas Page="p1|p2">
<Dict name="Student">
<FirstName>Sun</FirstName>
<LastName>Wjcx.com</LastName>
</Dict>
<Dict name="SexNo">
<item value="1">女</item>
<item value="2">男</item>
<IsComboBox>Yes</IsComboBox>
</Dict>
</DictDatas>
<searchFields Page="p1|p2">
<searchField name="SchoolInfo">
<ID>00.00</ID>
<SchoolName>Whut.Seu</SchoolName>
<Address>Wuhan.NanJing</Address>
</searchField>
</searchFields>
</campaign>
</campaigns>
</RootConfig>
1、使用XmlDocument
XmlDocument是以基於文檔結構模型的方式讀取.XML文件,可以把.XML文件看作是由文檔聲明(Declare)、元素(Element)、屬性(Attribute)、文本(Text)等構成的一棵樹,最開始的一個結點爲根結點,每個結點都可以有自己的子結點,得到一個結點後,可以通過一系列屬性或方法得到結點的值或其它屬性:
例:xn代表一個結點
xn.Name; // 這個結點的名稱
xn.Value; // 這個結點的值
xn.ChildNodes; // 這個結點的所有子結點鏈表
xn.ParentNode; // 這個結點的父結點
使用時首先聲明一個XmlDocument對象,調用Load方法,從指定路徑加載XML文件,推薦格式:
XmlDocument doc = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true; // 忽略文檔裏面的註釋
settings.IgnoreWhiteSpace = true; // 忽略空白
XmlReader reader = XmlReader.Create(@"..\..\sqh.xml", settings);
doc.Load(reader);
具體屬性和方法:
- XmlNode xnCamps = doc.SelectSingleNode("campaigns"); // 定位結點
- XmlNodeList campList = doc.SelectNodes("campaign"); // 定位結點鏈表
- XmlNodeList campList = doc.SelectNodes("campaign[Year<='2016']");
關於定位結點,有必要學習XML文檔的查詢語言:xPath,待續…
foreach(XmlNode xnCamp in campList)
{
XmlElement xeCamp = (XmlElement)xnCamp; // 將節點轉換爲元素,便於得到節點的屬性值
string nameCamp = xeCamp.Name;
string yearCamp = xeCamp.GetAttribute("Year").ToString();
string yearCamp = xeCamp.Attributes["Year"].Value; // 此2行代碼等價
XmlElement xeDict = (XmlElement)xeCamp.SelectSingleNode("DictDatas");
foreach(XmlNode xnDict in xeDict.ChildNodes)
{
XmlElement xeDict = (XmlElement)xnDict;
string isComboBox = xeDict["ComboBox"].InnerText;
XmlNodeList itemList = xeDic.SelectNodes("item");
foreach (XmlNode xnItem in itemList)
{
XmlElement xeItem = (XmlElement)xnItem;
string value = xeItem.GetAttribute("value").ToString();
string innerText = xeItem.InnerText;
}
}
}
以上代碼僅供學習參考,歡迎批評指正。
2、使用XmlTextReader
待續吧…
3、使用 Linq to Xml
首先了解下Linq,OK.
Linq (Language Itergrated Query,語言集成查詢) 是內置於C#中的一種數據查詢語言,允許以數據庫查詢的方式查詢數據集合,可以在大型的對象集合、XML、數據庫中查詢數據。不同的Linq變體(Linq to Objects、Linq to Entities、Linq to XML等)可以用於查詢、處理不同的數據源(數據庫和XML等)。
Linq查詢
a. 查詢語法 Query Syntax
聲明形式。利用查詢表達式。簡單易理解,推薦。
查詢表達式:from…select子句,group子句,where子句,join子句,orderby子句等。
· join 子句
用一個查詢搜索兩個列表中的相關數據,用鍵字段把結果鏈接起來。
from c in Table1
join o in Table2 on c.ID equals o.ID
· group 子句
分組鍵用 key 區分,返回結果 res 是關於 key 的可枚舉類型(分組),每個組也是可枚舉類型。
b. 方法語法 Method Ayntax
命令形式。利用標準查詢運算符。特殊情況需要傳送函數或方法,以委託的形式。注意,方法調用順序並不固定,因爲Linq方法調用返回的類型都實現了 IEnumerable<T> 接口,但是應根據查詢特性,合理安排調用順序。
System.Linq.Enumerable類聲明瞭標準查詢運算符的方法,是擴展了泛型 IEnumerable<T> 的 擴展方法:公共靜態方法,參數列表以 this 開始!
· 直接語法調用:Enumerable.Function(可枚舉類型實例);
· 擴展語法調用:可枚舉類型實例.Function();或 可枚舉類型實例.Function(Lambda表達式);
注:返回結果res爲 可枚舉類型,內存中的表示形式:
其中,res 並不保存查詢結果,而是指向 IEnumerable<T>類型的對象。當處理枚舉類型時,查詢表達式纔會執行(延遲執行)。
聚合運算符:查詢大型數據集,分析查詢結果。
Count()、Max()、Min()、Average()、Sum()
投影 Projection:在查詢中創建新的對象。
a. 投影查詢的查詢語法
在select子句中利用 new{…} 創建新對象,不能採用 select + 字段列表 的形式。
b. 投影查詢的方法語法
調用Linq的 Select(Lambda表達式) 方法。
多級排序
a. 查詢語法
orderby + 字段列表。
b. 多級排序的方法語法
OrderBy().ThenBy()/ThenByDescending()方法。
組合查詢 group
把數據分解爲組,允許按組來排序、計算聚合值以及進行比較。分組產生的結果集實現了 Linq接口 IEnumerable<IGrouping>,它支持 key 屬性,所以組合查詢中的數據通過一個鍵(Key)字段來組合,每個組中的所以數據共享這個字段值。
<-!- 幾種常用方法 -!->
◊. 分區運算符
- Take():從查詢結果中提取前n個結果;
- Skip():與Take()相反,跳過前n個結果,返回剩餘的結果;
◊. 條件查詢運算符
- First():返回結果集中第一個匹配給定條件的元素;
- FirstOrDefault():查詢條件不滿足,返回默認元素,而不必添加錯誤處理代碼;
◊. 標準的集(合)運算符 set operator
- Intersect():交集,QryRes1.Intersect(QryRes2);
- Except():差集,QryRes1.Except(QryRes2);
- Union():並集,QryRes1.Union(QryRes2);
Linq to XML
構建對象
C#:利用匿名類型 var 和對象初始化器。
Linq to XML:函數構建方式 (Function Construction)。此方式可以創建XML文檔,並且可以反映XML文檔的嵌套結構。需要引用命名空間:using System.Xml.Linq;
◊ . XDocument:XML文檔聲明。
◊ . XElement:元素。
◊ . XAttribute:特性。
XDocument personsDoc = new XDocument(
new XElement("persons", new XAttribute("Nationality","China"),
new XElement("person", new XAttribute("ID","101"), // 屬性
new XElement("Name","sqh"), // 元素
new XElement("Sex","male"),
new XElement("City", new XAttribute("Province", "ShanDong"), "WeiFang")
),
new XElement("person", new XAttribute("ID", "102"),
new XElement("Name", "pm"),
new XElement("Sex", "female"),
new XElement("City", new XAttribute("Province", "SiChuan"), "NanChong")
)
));
personsDoc.Save/Load(); // 保存/加載
XElement root = personsDoc.Root; // 根結點
IEnumerable<XElement> rootChilds = root.Elements("person");
foreach (XElement xe in rootChilds){
xe.Name.ToString(), xe.Attribute("ID").Value // 結點/子結點名字及屬性
xe.Element("City").Value, xe.Element("City").Attribute("Province").Value
}
// 增-Add、刪-Remove、改-SetElement
root.SetAttributeValue("民族", "漢"); // 增加/修改屬性
root.Attribute("民族").Remove(); // 刪除屬性
root.Add(new XElement("person", new XAttribute("ID","103"), // 增加結點
new XElement("Name", "ymn"),
new XElement("Sex", "female"),
new XElement("City", new XAttribute("Province", "HuBei"), "XianNing")
));
xe.Remove(); // 刪除結點
利用 Linq 查詢表達式進行 XML 樹搜索。
// 查 - Linq to Xml
var res = from xe in root.Elements("person")
where int.Parse(xe.Attribute("ID").Value) <= 102
select new { Name = xe.Element("Name").Value, City = xe.Element("City").Value};
參考鏈接:
c# 讀取XML - 1; - c# 讀取XML - 2;
關於XmlReader/XmlWriter 類;