訪問XML的方法

來源:互聯網
上載者:User

      昨天用wpf的時候要訪問xml,弄了很久,所以記錄一下。

     C#3.0提供了輕型的XmlReader、XmlWriter類和完全文檔對象模式(DOM)的XmlDocument類。這也是我昨天鬱悶半天的原因。以前用過XmlTextReader,也沒搞太懂,就是找到了方法,貼上代碼。看懂下了事。

在這個部落格可以找到原理:http://www.cnblogs.com/xdesigner/archive/2008/05/15/1198398.html

整個部落格可以看到xml操作方法:http://www.cnblogs.com/surfsky/archive/2007/03/13/673625.html

     先上原理:

     XmlReader是串流模型,所謂串流是指將XML文檔當做一個資料流來進行處理,逐個處理XML文檔中的資料。這種模型下,讀取快,記憶體佔用少,效能也就好。它的缺點也明顯(昨天我就是在這上面悶了很久):1.只能讀取不能修改;2.不能使用XPath技術;3.介面簡單,處理方法比較少。

System.Xml空間
    以下類適合快速流式讀寫XML檔案(註:DOM適合隨機讀寫)
    XmlReader, XmlWriter,
    XmlTextReader, XmlTextWriter
    XmlValidatingReader, XmlValidatingWriter    添加了DTD和模式驗證,因此提供了資料的有效性驗證
    XmlNodeReader, XmlNodeWriter                把XmlNode作為其源

      XmlDocument是DOM處理模型,使用文件物件模型的思想解析整個XML文檔,在記憶體中產生一個對象樹來表述XML文檔。可以使用XmlElement對象來影射XML文檔中的一個元素,使用XmlAttribute對象來影射到XML文檔中的一個屬性。這樣通過編程可以方便的操作XML,比如遞迴遍曆XML文檔的一部分或全部,可以像樹狀結構插入,修改或刪除XML元素,可以設定XML元素的屬性。

       在DOM模式下,我們可以使用XPath技術在XML文檔樹狀結構中進行快速檢索和定位,這為處理XML文檔帶來比較大的方便。

經常用到的幾個DOM的類型;

XmlNode 是DOM結構中的所有類型的基礎類型,它定義了所有XML節點的通用屬性和方法,是XMLDOM的基礎。它具有一個ChildNodes屬性,表示它所包含的子XML節點。

    XmlAttribute 表示XML屬性,它只儲存在XmlElement的Attributes 列表中。

    XmlDocument表示XML文檔本身,是XMLDOM模型中的頂級對象,它用於對XML文檔進行整體的控制,並且是其它程式訪問XML文檔對象樹的唯一入口。

    XmlLinkedNode在XmlNode的基礎上實現了訪問前後同級節點的方法。

    XmlElement元素表示XML元素。是XMLDOM中使用最多的物件類型。它具有Attributes屬性可以處理它所擁有的屬性,可以使用ChildNodes屬性獲得它所有的子節點。並提供了一些添加和刪除子節點的方法。

 

 

 

 

 

 

 

 

 

下面看一張XDocument的(有個問題想問,XDocument和XElement的關係是?):

 

再上建議:

  使用XmlDocument:1.傳統的DOM方法適用。2.所需的整個文檔皆在記憶體中。3.必須在記憶體中向前或向後遍曆以及更新。

  使用XmlReader/XmlWriter:1.必須適用流方法。2.必須要求進行最快的處理。3.要處理較大的文檔並且無法一次性載入全部文檔。

  使用XElement/XDocument:1.用代碼構建xml聲明。2.LINQ的查詢能力有助於流方法。3.需要一種針對大多數開發人員的更易讀的XML編程文法。

                                         4.要求使用查語義在記憶體中遍曆。

博文後面的代碼比較多,我只說我用到的。

XmlReader有個很經典的:

XmlReader reader = xDoc.CreateRedaer();reader.Settings.CheckCharacters = true;int level = 0;while(reader.Reader()){  switch(reader.NodeType)  {      case XmlNodeType:           Display(level,"CDATA:{0}",reader.Value);           break;      case XmlNodeType.Comment:           Display(level,"Comment:{0}",reader.Value);           break;      case XmlNodeType.DocumentType:           Display(level,"DOCTYPE:{0}=   {1}",reader.Name,reader.Value);           break;      case XmlNodeType.Element:           Display(level,"Element:{0}",reader.Name);           level++;           while(reader.MoveToNextAttribute())           {               Display(level,"ATTRIBUTE:       {0}='{1}'",reader.Name,reader.Value);           }           break;      case XmlNodeType.EndElement;           level--;           break;      case XmlNodeType.EntityReference:           Display(level,"ENTITY:{0}",reader.Name);           break;      case XmlNodeType.ProcessingInstruction:           Display(level,"INSTRUCTION:   {0}={1}",reader.Value);           break;      case XmlNodeType.Text;           Display(level,"TEXT:{0}",reader.Value);           break;      case XmlNodeType.XmlDeclaration:           Display(level,"DECLARATION:                      {0}={1}",reader.Value);           break;  }}static void Display(int indentLevel,string format,params object[] args){    for(int i=0;i<indentLevel;i++)         Console.Write(" ");    Console.WriteLine(format,args)}
XDocument的(網上有更詳細的,這個是我為瞭解決自己的問題寫的,主要是遍曆某個節點下的全部子節點):
 XmlDocument xmldoc = new XmlDocument();            xmldoc.Load(filePath);            XmlNodeList topM = xmldoc.DocumentElement.ChildNodes;            foreach (XmlElement element in topM)            {                if(element.Name=="Vocabulary")                {                    XmlNodeList nodelist = element.ChildNodes;                    Model.Vocabulary vocabulary = new Model.Vocabulary();                    foreach (XmlElement el in nodelist)                    {                        if (el.Name == "Word")                            vocabulary.Word = el.InnerText;                        else if (el.Name == "Explain")                            vocabulary.Explain = el.InnerText;                        else if (el.Name == "IsLastSelected")                            vocabulary.IsLastSelected = el.InnerText=="0"?false:true;                    }                    vocabularies.Add(vocabulary);                }

OK,先到這裡,以後碰到問題再補上增刪的。

繼續:

關於linq to xml的,關於Descentdants函數。具體可以參看:http://www.programbbs.com/doc/4564.htm

Desentdants英文意思是後代,晚輩。也就是這個函數是用於獲得某個Element下的指定子Element。

foreach (XElement elem in doc.Elements(\"Customers\").Descendants(\"Customer\"))     {    Console.WriteLine(string.Format(                                 \"Customer ID : {0}, Name : {1}, Address : {2}\",                                   elem.Attribute(\"ID\").Value,                                    elem.Attribute(\"Name\").Value,                                   elem.Attribute(\"Address\").Value));} 
<?xml version=\"1.0\" encoding=\"utf-8\"?> <Customers><Customer ID=\"A0001\" Name=\"Tom\" Address=\"Taipen\" />  <Customer ID=\"A0002\" Name=\"Mary\" Address=\"LD\" />  <Customer ID=\"A0003\" Name=\"Jeff\" Address=\"YW\" /> </Customers> 
特別的,當xml中包含了Namespace時,傳入的Descendants的指定Element名稱必包含Namespace,

Descendants函數接收的是一個XName的元素,它隱含了\運算元,顯然剛只得到了Element的LocalName。可以這樣做:

var cstr = (from s1 in doc.Descendants() where s1.Name.LocalName==\"Connection\" select s1).First();

var cstr = (from s1 in doc.Descendants(doc.Root.Name.Namespace+\"Connection\" select s1).First();

 

繼續:Linq to xml 的Elements()函數

(發現很多方法都可以輕鬆搞定我那個問題)

參考網站:http://www.cnblogs.com/ucetgg/archive/2009/04/23/1441739.html

var name = from nm in xelement.Elements("Employee") where (string)nm.Element("Sex")=="Female" select nm;

 

繼續:處理非法字元

XElement和XmlWriter方法:

XElement可以直接處理轉義也可以用XCData對象處理。

string invalidChars =@"<>\&";XElement element = new XElement("Root",                        new XElement("InvalidChars1",                            new XCData(invalidChars)),                        new XElement("InvalidChars2", invalidChars));

InvalidChars1將儲存為<![CDATA[<>\&"]>,InvalidChars2將轉義儲存。

附上轉義表:

  <   &lt;

  <   &gt;

  "    &quot;

  '    &apos;

  &   &amp;

  XmlWriter處理可以使用WriteCData方法將非法字元封裝在CDATA片段中,另一種使用WriteElementString方法。   

string invalidChars =@"<>\&";XmlWriterSettings settings = new XmlWriterSettings();settings.Indent = true;using(XmlWriter writer = XmlWriter.Create(Console.Out,settings)){writer.WriteStartElement("root");writer.WriteStartElement("InvalidChars1");writer.WriteCDate(invalidChars);writer.WriteEndElement();writer.WriteElementString("InvalidChars2",invalidChars);writer.WriteEndElement();}

XmlDocumenthe和XmlElement處理方法:

放置於CDATA片段中,並添加至XmlElement的InnerXML屬性中。

string invalidChars =@"<>\&";XmlElement invalidElement1 = xmlDoc.CreateElement("InvalidChars1");invalidElement1.AppendChild(xmlDoc.CreateCDataSection(invalidChars);

通過賦值給InnerText屬性令XmlElement類為封裝資料。

string invalidChars =@"<>\&";XmlElement invalidElement2 = xmlDoc.CreateElement("InvalidChars2");invalidElement2.InnerText = invalidChars;

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.