2012年1月9日 星期一

C#角度看XML格式讀取

XML以程式語言的角度來看的目的是什麼?就是為了知道怎麼讀寫,怎麼解析內容


讀寫的方式有很多種,XmlReader, XmlDocument......能控制的角度,能使用的函式也有不同
在此先介紹 XmlDocument


先將 XmlDocument 產生物件之後,可呼叫 Load() 來載入 XML 檔,如果用 LoadXml() 則可以由字串來讀入,也就是一個傳入路徑,一個傳入String,之後便透過節點的方式,指定要讀取哪一個階層的節點們,然後用迴圈逐一的將內容讀取出來,以下為簡單的範例程式
               
 XmlDocument XmlDoc = new XmlDocument( );
 XmlDoc.Load( @"C:\XmlFileName.XML" );
 XmlNodeList NodeLists = XmlDoc.SelectNodes( "Root/MyLevel1" );


 foreach ( XmlNode OneNode in NodeLists )
 {
     String StrAttrName = OneNode.Attributes.Name;
     String StrAttrValue = OneNode.Attributes[ "
 MyAttr1 " ].Value; 
     String StrAttrValue = OneNode.InnerText
;

  }

如此便可將 <MyLevel1> 這一層的節點都抓出來,下面這個XML範例來抓應該會抓到五個,然後讀取每一個的 MyAttr1 屬性的內容以及Node的InnerText。(備註:但是這樣的作法,是固定的沒有彈性的,必須每個<MyLevel1>節點都要具備MyAttr1,否則就會有Exception,而某個Node如果有多個Attribute則不會讀取到)。同樣的,如果用XmlNodeList NodeLists = XmlDoc.SelectNodes( "Root/MyLevel1/MyLevel2" );就可以讀取這層的四個節點了。 接下來,我們看看XML的格式



<?xml version="1.0" encoding="utf-8"?>
<Root>
   <MyLevel1 MyAttr1 = "aaaaa" > WXYZ 
       <MyLevel2 MyAttr10 = "UUUUUUUUU" />
       <MyLevel2 MyAttr10 = "KKKKKKKKK>QWER</MyLevel2>
   </MyLevel1>
   <MyLevel1 MyAttr1 = "aaaaa" > WXYZ 
       <MyLevel2 MyAttr10 = "VVVVVVVVV" />
       <MyLevel2 MyAttr10 = "PPPPPPPPP>QWER</MyLevel2>
   </MyLevel1>
   <MyLevel1 MyAttr1 = "bbbbb" MyAttr2 = "bbbbb"/>
   <MyLevel1 MyAttr1 = "UUUUUUUUU" />
</Root>





Root是根節點,一個檔案只能有一個,接下來,每個<>所括住的都是一個節點,並且分層次存在,層次的分法,是相同的標記如果用<>與</>來分兩行來包住其他的<>節點,那這些被包起來的,就會是下一層。而每個節點可以有Attributes,每個屬性可以存放一個數值(或字串),而如果節點的表示法用 用<>與</>來表示,且中間夾了數值(或字串),則這個稱為InnerText。(備註:另外還有InnerXml,這個是包含子節點都算進去,有點複雜,也可先不理會),所以用程式來讀取其Attributes的Value,或是讀取InnerText,在轉成需要的格式,就是XML的讀取應用方式了,








接下來,挑戰一下有難度的格式吧!!





<?xml version="1.0" encoding="utf-8"?>
<Root>
   <MyLevel1 MyAttr1 = "aaaaa" > WXYZ 
       <MyLevel2 MyAttr100 = "第二層01" />
       <MyLevel2>IN_002</MyLevel2>
   </MyLevel1>
   <MyLevel1 MyAttr1 = "bbbbb" > WXYZ 
       <MyLevel2 MyAttr100 = "第二層02" MyAttr101 = "第二層002" />
       <MyLevel2>IN_003</MyLevel2>
   </MyLevel1>
   <MyLevel1 MyAttr1 = "ccccc" > WXYZ 
       <MyLevel3 MyAttr100 = "第二層03" />
       <MyLevel3>IN_004</MyLevel3>
   </MyLevel1>
   <MyLevel1 MyAttr1 = "ddddd" > WXYZ 
       <MyLevel2 MyAttr100 = "第二層04" />
       <MyLevel2>IN_005</MyLevel2>
   </MyLevel1>
   <YouLevel1 MyAttr1 = "ddddd" > WXYZ 
       <MyLevel2 MyAttr100 = "第二層05" />
       <MyLevel2>IN_006</MyLevel2>
   </YouLevel1>
   <MyLevel1 MyAttr1 = "bbbbb" MyAttr2 = "bbbbb"/>
   <MyLevel1 MyAttr10 = "UUUUUUUUU" />
   <MyLevel1>IN_007</MyLevel1>
</Root>











不管他格式多複雜,用以下的方式,就可以讀取節點的每個Attribute,以及InnerText了,且,不會去嘗試讀取不存在的Attribute,所以不會發生Exception。




foreach ( XmlNode OneNode in NodeLists )
{
String StrNodeName = OneNode.Name.ToString();
foreach ( XmlAttribute Attr in OneNode.Attributes )
{
String StrAttr = Attr.Name.ToString( );
String StrValue = OneNode.Attributes[ Attr.Name.ToString( ) ].Value;
String StrInnerText = OneNode.InnerText;
}
}






再來,就是怎麼選擇要讀取哪一層,如果用以下的方式會讀取在Root底下的MyLevel1底下的MyLevel2,對,MyLevel3就不會被讀取了。還有YouLevel1底下的MyLevel2也不會被讀取,
所以會讀取到6個節點。
XmlNodeList NodeLists = XmlDoc.SelectNodes( "Root/MyLevel1/MyLevel2" );





如果用以下的方式會讀取在Root底下的MyLevel1 ,則會讀取到7個節點
XmlNodeList NodeLists = XmlDoc.SelectNodes( "Root/MyLevel1" );


沒有留言:

張貼留言