讀寫XML

  XML和HTML都是基於SGML(Standard Generalized Markup Language,標準通用標記語言)的,但是XML和HTML卻有着很大的區別,這些區別不僅僅在於格式上的區別,還在於使用性、可擴展性等等。

14.2.1 XML與HTML
  XML標記語言和HTML標記語言有着極大的不同,在應用程序開發中,XML標記語言能夠適應於大部分的應用程序環境和開發需求。這些需求是HTML標記語言無法做到的,XML標記語言和HTML標記語言的具體區別如下所示。
1)HTML標記是固定的,並且是沒有層次的,在HTML文檔中,用戶無法自行創建標籤,例如<book>這樣的標籤瀏覽器很可能解析不了,HTML中標記的作用是描述數據的顯示方式,這種方式只能交付給瀏覽器進行處理,而HTML文檔中的標記都是獨立存在的,沒有層次。
2)XML的標記不是固定的且是有層次的,在XML文檔中,用戶可以自行創建標籤,例如<day>這樣的標籤,XML標記不能夠描述網頁的外觀和內容,XML只能夠描述內容的數據結構和層次,在瀏覽器中瀏覽XML文檔,也可以發現XML標記是有層次的。
  在Visual Studio 2008中,.NET Framework提供了System.XML命名空間,該命名空間提供了一組可擴展類使得開發人員能夠輕鬆的讀、寫、以及編輯XML文本。

14.2.2 創建XML文檔
  使用Visual Studio 2008能夠創建XML文檔,創建和使用XML文檔無需XML語法分析器來專門負責分析語法,在.NET Framework中已經集成了可擴展類。右擊現有項,單擊【添加新項】選項,選擇XML文件,
  創建完成後,就需要向XML文檔中編寫XML標記,以下是一個完整的XML文檔示例。

+展開
-XML<?xml version="1.0" encoding="utf-8" ?>
<Root>
    <ShopInformation area="Asia">
        <Shop place="Wuhan">
            <Name>武漢電腦城</Name>
            <Phone>123456789</Phone>
            <Seller>J.Dan</Seller>
            <Seller>Bill Gates</Seller>
        </Shop>
        <Shop place="ShangHai">
            <Name>武漢電腦城</Name>
            <Phone>123456789</Phone>
            <Seller>Bill Gates</Seller>
        </Shop>
    </ShopInformation>
    <ShopInformation area="USA">
        <Shop place="S">
            <Name>PC STORE</Name>
            <Phone>123456789</Phone>
            <Seller>J.Dan</Seller>
            <Seller>Bill Gates</Seller>
        </Shop>
        <Shop place="S.K">
            <Name>Windows Mobile Store</Name>
            <Phone>123456789</Phone>
            <Seller>Bill Gates</Seller>
        </Shop>
    </ShopInformation>
</Root>
  上述XML文檔使用了自定義標記對商城進行了描述,包括商城所在地、商城名稱、電話號碼以及負責人等。編寫XML文檔時,開發人員能夠自定義標籤進行文檔描述,但是在XML文檔的頭部必須進行XML文檔聲明,示例代碼如下所示。

+展開
-XML<?xml version="1.0" encoding="utf-8" ?>
  上述代碼在XML文檔頭部進行了聲明,表示該文檔是一個XML文檔,並且說明該文檔的版本爲1.0的XML文檔,該文檔還可以包含一個encoding屬性,指明文檔中的編碼類型。聲明該文檔是一個XML文檔後,則需要在XML文檔中編寫根標記,這個標記可以是開發人員自定義標記名稱,在這裏被命名爲Root,示例代碼如下。

+展開
-XML<Root>
<!-- 根標記內的所有內容 -->
</Root>
  上述代碼創建了一個根標記,在這裏命名爲Root。在XML文檔中,所有的標記都應該被包含在一個根標記中,這樣不僅方便描述也方便查閱。XML文檔中的根標記不能夠重複使用,如果重複使用則會提示異常。
  在根標記內,應該編寫需要描述的信息的標記。在這裏,描述一個商城需要的一些屬性,包括商城所在的州、所在地以及商城的主營類型等,通過XML標記語言可以自行創建標記來描述,示例代碼如下所示。

+展開
-XML    <ShopInformation area="USA"> <!--地區描述-->
        <Shop place="S"> //位置描述
            <Name>PC STORE</Name><!--商城名稱-->
            <Phone>123456789</Phone><!--商城電話-->
            <Seller>J.Dan</Seller><!--商城銷售人員-->
            <Seller>Bill Gates</Seller>
        </Shop>
        <Shop place="S.K">
            <Name>Windows Mobile Store</Name>
            <Phone>123456789</Phone>
            <Seller>Bill Gates</Seller>
        </Shop>
    </ShopInformation>
  上述代碼對商城的信息進行了描述,這些標籤的意義如下所示:
1)ShopInformation:商城信息,包括area屬性來描述所在州或板塊,這裏說明了是在USA地區。
2)Shop:商城在該板塊的所在州、省市等信息。
3)Name:商城的名稱。
4)Phone:商城的聯繫電話。
5)Seller:商城的銷售人員。
  這些標籤都是用戶自定義的,XML文檔允許開發人員自定義標籤並,另外,XML文檔也不侷限所要描述的對象格式。例如當上述代碼也可以編寫另外一種樣式時,同樣能夠被XML所識別,示例代碼如下所示。

+展開
-XML    <ShopInformation>
        <Area name="Usa"><!--另一種地區表示方式-->
            <Shop>
                <Name>PC STORE</Name>
                <Phone>123456789</Phone>
                <Seller>J.Dan</Seller>
                <Seller>Bill Gates</Seller>
                <Place>S.K</Place><!--地區直接放在描述中-->
            </Shop>
            <Shop>
                <Name>Windows Mobile Store</Name>
                <Phone>123456789</Phone>
                <Seller>Bill Gates</Seller>
                <Place>S</Place>
            </Shop>
        </Area>
    </ShopInformation>
  技巧:良好的縮進能夠讓XML文檔更加方便閱讀,同時XML文檔是大小寫敏感的,對於XML標記,標記頭和標記尾的大小寫規則必須匹配。

14.2.3 XML控件
  在ASP.NET中提供了針對XML讀寫的控件XML控件,XML控件可以很好的解決XML文檔的顯示問題,如果需要瀏覽XML文檔的數據,則只需要編寫XML控件中的DocumentSource屬性即可,示例代碼如下所示。

+展開
-HTML<body>
    <form id="form1" runat="server">
    <div>
    <asp:Xml ID="xml1" runat="server" DocumentSource="~/XMLFile1.xml"></asp:Xml><!--使用XML控件-->
    </div>
    </form>
</body>
運行後如圖14-3所示。

圖14-3 XML控件
  運行後會發現XML文檔的內容都顯示出來了,但是卻沒有層次感,因爲XML控件並沒有把記錄分開,而是連續的呈現XML文檔的內容。如果需要按照規範或開發人員的意願呈現給瀏覽器,則必須使用XSL樣式表。

14.2.4 XML文件讀取類(XmlTextReader)
  XmlTextReader類屬於System.Xml命名空間,XmlTextReader類提供對XML數據的快速、單項、無緩衝的數據讀取功能,因爲XmlTextReader類是基於流的,所以使用XmlTextReader類讀取XML內容只能夠從前向後讀取,而不能逆向讀取。
  因爲XmlTextReader類的流形式,節約了讀取XML文檔的時間,也大量的節約了讀取XML所需花費的內存空間,當需要讀取XML節點時,只需要使用XmlTextReader類的Read()方法即可,示例代碼如下所示。

+展開
-C#            XmlTextReader rd = new XmlTextReader(Server.MapPath("XMLFile1.xml")); //構造函數
            while (rd.Read())//遍歷節點
            {
                Response.Write("Node Type is : " + rd.NodeType +" <br/>");//輸出Node
                Response.Write("Name is : " + rd.Name + " <br/>");//輸出Name
                Response.Write("Value is :" + rd.Value + " <br/>"); //輸出Value
                Response.Write("<hr/>");
            }
  上述代碼使用XmlTextReader類的構造函數創建了XmlTextReader對象,並通過使用XmlTextReader類的Read()方法進行XmlTextReader對象的遍歷。遍歷XML文檔後,需要使用Close方法進行XmlTextReader對象的關閉操作,這一點是非常重要的,如果不使用XmlTextReader類的Close方法,則相應的XML文件正在被進程使用,只有使用了Close方法才能將相應的文件關閉掉。示例代碼如下所示。

+展開
-C#rd.Close();//關閉Reader

  在使用XmlTextReader類讀取XML文件中相應的節點時,XmlTextReader類的NodeType會檢查節點的類型,而XmlTextReader類的Name和Value會分別檢查節點的名稱和值,相應的XML代碼如下所示。

+展開
-XML        <Shop place="Wuhan">
            <Name>武漢電腦城</Name>
            <Phone>123456789</Phone>
            <Seller>J.Dan</Seller>
            <Seller>Bill Gates</Seller>
        </Shop>
  上述代碼中,使用XmlTextReader類進行讀取,則Shop節點的NodeType爲Element,Name的值爲Shop,Value的值爲空。XML文檔中不止以上幾種節點類型,XmlNodeType也包括其他節點類型,這些類型如下所示。
1)Attribut:XML元素的屬性。
2)CDATA:用於轉義文本塊,避免將文本塊識別爲標記。
3)Comment:XML文檔的註釋。
4)Document:作爲文檔樹的根的文檔對象,可供每個XML文檔進行訪問。
5)DocumentType:XML文檔類型的聲明。
6)Element:XML元素。
7)EndElement:當XmlTextReader達到元素末尾時返回。
8)Entity:實體聲明。
9)Text:元素的文本內容。
10)WhiteSpace:標記間的空白。
11)XmlDeclaration:XML節點聲明,它是文檔中的第一個節點。
  在XML文檔中,空白標記和根節點的節點類型是不相同的,XmlTextReader類讀取XML文件並遍歷節點類型,根節點和空白節點遍歷後結果如下所示。
Node Type is:XmlDeclaration
Nameis:xml
Value is:version="1.0" encoding="utf-8"
Node Type is:Whitespace
Nameis:
Value is:
  其中根節點的節點類型爲XmlDeclaration,Value值爲version="1.0" encoding="utf-8"。

14.2.5 XML文件編寫類(XmlTextWriter)
  XmlTextWriter類屬於System.Xml命名空間,同XmlTextReader類相同的是,XmlTextWriter類同樣提供沒有緩存,直向前的方式進行XML文件操作,但是與XmlTextReader類操作相反,XmlTextWriter類執行的是寫操作。XmlTextWriter類的構造函數包括三種重載形式,分別爲一個字符串、一個流對象和一個TextWriter對象。通過使用XmlTextWriter類可以動態的創建XML文檔,示例代碼如下所示。

+展開
-C#            XmlTextWriter wr = new XmlTextWriter("newXml.xml", null);//讀取XML
            try
            {
                wr.Formatting = Formatting.Indented;//格式化輸出
                wr.WriteStartDocument();//開始編寫文檔
                wr.WriteStartElement("ShopInformation");//編寫節點
                wr.WriteStartElement("Shop");//編寫節點
                wr.WriteAttributeString("place", "北京");//編寫節點
                wr.WriteElementString("Name", "中關村");//編寫節點
                wr.WriteElementString("Phone", "123456"); //編寫節點
                wr.WriteElementString("Seller", "Guojing");//編寫節點
                wr.WriteEndElement();//結束節點編寫
                wr.WriteEndElement();//結束節點編寫
                Response.Write("操作成功");
            }
            catch
            {
                Response.Write("操作失敗");
            }
  上述代碼創建了一個XmlTextWriter對象並通過XmlTextWriter對象編寫XML文檔,在使用XmlTextWriter類構造函數時,可以指定編碼類型,或使用默認的編碼類型,若使用默認的編碼類型,參數傳遞null即可,默認編碼類型將爲UTF-8,示例代碼如下所示。

+展開
-C#XmlTextWriter wr = new XmlTextWriter("newXml.xml", null);//創建寫對象
  使用了XmlTextWriter類創建對象後,則需要使用XmlTextWriter對象的Formatting方法指定輸出的格式,示例代碼如下所示。

+展開
-C#wr.Formatting = Formatting.Indented;//格式化輸出
  指定了輸出格式之後,則需要開始爲XML文檔創建節點,在創建節點前,首先需要聲明XML文檔,則必須輸出<?xml version="1.0" encoding="utf-8" ?>聲明,聲明1.0版本的xml文檔代碼如下所示。

+展開
-C#wr.WriteStartDocument();//開始編寫節點
聲明文檔後就可以使用WriteStartElement進行節點的創建,創建節點代碼如下所示。

+展開
-C#wr.WriteStartElement("Shop");//開始編寫節點
  上述代碼創建了Shop節點,如果需要爲該節點創建place=“北京”屬性則需要使用WriteAttributeString方法進行創建,示例代碼如下所示。

+展開
-C#wr.WriteAttributeString("place", "北京");//編寫屬性
創建了父節點之後,可以通過WriteElementString方法創建子節點,示例代碼如下所示。

+展開
-C#wr.WriteElementString("Name", "中關村");//創建子節點
節點全部創建完成後,需要使用WriteEndElement方法進行尾節點的編寫,示例代碼如下所示。

+展開
-C#wr.WriteEndElement();//結束節點編寫
一個XML文檔就編寫完畢了,編寫完成並不能自動的更新XML文檔,還需要使用Flush方法進行數據更新,更新完畢後還需要關閉XmlTextWriter對象示例代碼如下所示。

+展開
-C#wr.Flush();//更新文件
wr.Close();//結束寫對象
使用Flush方法就能夠將XML數據保存在文件中,運行後XML文檔結構如下所示。

+展開
-XML<?xml version="1.0" encoding="utf-8" ?>
<ShopInformation>
    <Shop place="北京">
        <Name>中關村</Name>
        <Phone>123456</Phone>
        <Seller>Guojing</Seller>
    </Shop>
</ShopInformation>

14.2.6 XML文本文檔類(XmlDocument)
  XML文檔在內存中是以DOM爲表現形式的,DOM(Document Object Model)是對象化模型,DOM是以樹的節點形式來標識XML數據,14.2.2中的XML文檔讀入DOM結構中,則在內存中的構造圖如圖14-5所示。

圖14-5 XML文檔構造
  XmlDocument類同樣也屬於命名空間System.Xml,XmlDocument類可以實現第一、第二級的W3C DOM。它使用DOM以一個層次結構樹的形式將整個XML數據加載到內存中,從而能夠使開發人員能夠對內存中的任意節點進行訪問、插入、更新和刪除。由於XmlDocument類,簡化開發人員對XML文檔進行訪問、插入和刪除等操作。
  XmlDocument類繼承自System.Xml.XmlNode,該抽象類表示單個節點並具有基本的屬性和方法來操作節點。利用XmlDocument對象的DocumentElement屬性能夠表示單個節點並進行操作。XmlDocument對象的DocumentElement返回一個指向文檔元素的索引,可以通過讀取給定的節點的HanChildNodes屬性判斷是否包括子節點。另外,使用XmlDocument對象的HasChildNodes和ChildNodes屬性可以讀取和遍歷XML文件,示例代碼如下所示。

+展開
-C#        protected void Page_Load(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();//創建XmlDocument對象
            doc.Load(Server.MapPath("newXml.xml"));//載入文件
            Response.Write("讀取中..<hr/>");
            XmlNode node = doc.DocumentElement; //讀取節點
            output(node); //使用輸出函數
            Response.Write("讀取完畢..<hr/>");//輸出HTML字串
        }
        protected void output(XmlNode node)
        {
            if (node != null)//如果節點不等於空
            {
                format(node);//格式化輸出
            }
            if (node.HasChildNodes)//判斷是否包括子節點
            {
                node = node.FirstChild;//獲取子節點
                while (node != null)
                {
                    output(node);//使用遞歸
                    node = node.NextSibling;//遍歷節點值和信息
                }
            }
        }
        protected void format(XmlNode node)
        {
            if (!node.HasChildNodes)//判斷是否包括子節點
            {
                Response.Write("node name is" + node.Name);//輸出節點
                Response.Write("node value is" + node.Value);//輸出節點
                Response.Write("<br/>");
            }
            else
            {
                Response.Write(node.Name);
                if (XmlNodeType.Element == node.NodeType)//遍歷節點
                {
                    XmlNamedNodeMap map = node.Attributes;//遍歷節點
                    foreach (XmlNode att in map)
                    {
                        Response.Write("attrnode name is" + att.Name);//格式化輸出節點
                        Response.Write("attrnode value is" + att.Value);//格式化輸出節點
                        Response.Write("<br/>");
                    }
                }
            }
        }
  上述代碼通過使用XmlDocument類遍歷節點,使用XmlDocument類遍歷節點,首先需要創建一個XmlDocument對象,並使用Load方法加載一個XML文檔,示例代碼如下所示。

+展開
-C#XmlDocument doc = new XmlDocument();//創建XmlDocument對象
doc.Load(Server.MapPath("newXml.xml"));//載入XML文件
  創建對象之後,則需要使用遞歸的方法遍歷顯示每個節點。在遍歷節點的過程中,需要對每個節點進行是否有子節點的判斷,如果包括子節點,則先輸出子節點,如果沒有子節點則繼續輸出根節點。XmlDocument對象也可以向XML文檔中添加一個新的元素,示例代碼如下所示。

+展開
-C#            XmlDocument doc = new XmlDocument(); //創建XmlDocument對象
            doc.Load(Server.MapPath("newXml.xml"));//載入XML文件
            XmlNode node = doc.DocumentElement; //創建節點對象
            node.RemoveChild(node.FirstChild);//移除根節點
  上述代碼使用了XmlDocument對象的Load方法載入XML文檔,當需要插入XML數據時,則先需要移除根節點,移除根節點之後就能夠開始添加節點,示例代碼如下所示。

+展開
-C#            XmlNode Shop = doc.CreateElement("Shop");//創建節點Shop
            XmlNode shop1 = doc.CreateElement("Name");//創建節點Name
            XmlNode shop2 = doc.CreateElement("Phone");//創建節點Phone
            XmlNode shop3 = doc.CreateElement("Seller");//創建節點Seller
            XmlNode NameText = doc.CreateTextNode("NameText");//創建節點文本
            XmlNode PhoneText = doc.CreateTextNode("PhoneText"); //創建節點文本
            XmlNode SellerText = doc.CreateTextNode("SellerText");//創建節點文本
            shop1.AppendChild(NameText);//添加文本
            shop2.AppendChild(PhoneText); //添加文本
            shop3.AppendChild(SellerText);//添加文本
            Shop.AppendChild(shop1);//添加Shop子節點
            Shop.AppendChild(shop2); //添加Shop子節點
            Shop.AppendChild(shop3); //添加Shop子節點
            node.AppendChild(Shop); //添加Shop節點
  上述代碼分別爲節點添加子節點,併爲子節點添加文本,添加完成後,需要使用XmlDocument對象的Save方法進行保存,示例代碼如下所示。

+展開
-C# doc.Save("newXml.xml");
  使用XmlDocument對象的Save方法即可將XML內容保存在XML文檔中。使用XmlDocument對象不僅能夠讀取,新增XML文檔,還支持修改、刪除等操作,例如使用PrependChild和InsertBefore,InsertAfter等方法進行新增和刪除節點和子節點操作。
類別:Asp.Net/C#/WCF 作者:轉載 日期:2010-05-28 【評論:0 閱讀:163】 繁體中文<br/><br/><br/>本文來自<a href="http://www.code-design.cn">編程設計網</a>,轉載請標明出處:<a href="http://www.code-design.cn/blogdetail2540.html">http://www.code-design.cn/blogdetail2540.html</a>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章