Linq to XML 的寫作非常方便。以往要組一個 xml ,都必須從 XmlDocument 開始,現在使用 Linq to XML 就不用了。
範例1:
例如,下列程式碼//code 1 XElement el = new XElement("r", new XElement("invoice", new XElement("invoiceNumber", "AB12345678"), new XElement("invoiceDate", DateTime.Now) ) );產生的 xml 結果如下
<r> <invoice> <invoiceNumber>AB12345678</invoiceNumber> <invoiceDate>2008-09-01T10:08:22.9666505+08:00</invoiceDate> </invoice> </r>
這樣的方式極為簡便。
範例2:
如果要產生 namespace 呢? 以下的程式碼會產生 default namespace
//code 2 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement(ns + "r", new XElement(ns + "invoice", new XElement(ns + "invoiceNumber", "AB12345678"), new XElement(ns + "invoiceDate", DateTime.Now) ));產生如下的 xml
<r xmlns="http://www.compnay.com.tw/Invoice"> <invoice> <invoiceNumber>AB12345678</invoiceNumber> <invoiceDate>2008-09-01T10:16:48.2077244+08:00</invoiceDate> </invoice> </r>
範例3:
也可以使用如下的寫法,但效能會差一些,原因 runtime 要計算用了哪些 namespace。//code 3 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement("{http://www.compnay.com.tw/Invoice}r", new XElement("{http://www.compnay.com.tw/Invoice}invoice", new XElement("{http://www.compnay.com.tw/Invoice}invoiceNumber", "AB12345678"), new XElement("{http://www.compnay.com.tw/Invoice}invoiceDate", DateTime.Now) ) );結果是一樣的
<r xmlns="http://www.compnay.com.tw/Invoice"> <invoice> <invoiceNumber>AB12345678</invoiceNumber> <invoiceDate>2008-09-01T10:20:56.8615067+08:00</invoiceDate> </invoice> </r>
這樣的寫法雖然較容易了解,但較不容易修改,我個人不建議這樣的寫法。
範例4:
另外,注意到雖然我們沒有說要寫成 default namespace,但Linq to XML 會「自動」地視狀況修改。
我們可以使用 XAttribute 來使用 namesapce prefix。如下程式碼。
//code 4 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement("r", new XAttribute(XNamespace.Xmlns + "i", "http://www.compnay.com.tw/Invoice"), new XElement("invoice", new XElement("invoiceNumber", "AB12345678"), new XElement("invoiceDate", DateTime.Now) ) );結果如下。注意到這樣的方法,可以很方便地產生了一個 namespace prefix i,但卻沒有任何節點使用到這個 prefix
<r xmlns:i="http://www.compnay.com.tw/Invoice"> <invoice> <invoiceNumber>AB12345678</invoiceNumber> <invoiceDate>2008-09-01T10:27:11.773833+08:00</invoiceDate> </invoice> </r>
範例5:
使用下面的程式碼,就不難了解 xml namespace 的特殊
//code 5 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement("r", new XAttribute(XNamespace.Xmlns + "i", "http://www.compnay.com.tw/Invoice"), new XElement("{i}invoice", new XElement("invoiceNumber", "AB12345678"), new XElement("invoiceDate", DateTime.Now) ) );產生的xml 如下。xml:i="http:....." 這個 namespace 宣告了,卻沒有任何節點使用。i 是一個 namespace 的值,是inovice節點的 default namespace。invoiceNumber 與 invoiceDate的 namespace 卻是 ""。一個簡單的xml,卻有三個 namespace,基本上是錯誤的設計。
<r xmlns:i="http://www.compnay.com.tw/Invoice"> <invoice xmlns="i"> <invoiceNumber xmlns="">AB12345678</invoiceNumber> <invoiceDate xmlns="">2008-09-01T11:02:47.1886207+08:00</invoiceDate> </invoice> </r>
範例6:
如果要像 code 2,產生相同的結果,但不要每一個節點使用 ns + "xxx"這樣的方式可不可以呢?如下的程式碼會發生錯誤
//code 6, fails XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement("r", new XAttribute("xmlns", "http://www.compnay.com.tw/Invoice"), new XElement("invoice", new XElement("invoiceNumber", "AB12345678"), new XElement("invoiceDate", DateTime.Now) ) );
錯誤的訊息為 Unhandled Exception: System.Xml.XmlException: The prefix '' cannot be redefined from '' to 'http://www.compnay.com.tw/Invoice' within the same start element tag. 看來,沒有一個好的方法,將其他的節點批次地設為 default namespace了。必須每一個節點都如 code 2 一般,將每一個節點,一個個設 namespace。也沒有辦法設哪一個 namespace 為 default namespace。
範例7:
最後的範例,是 prefix namespace, 請與範例2 對照
//code 7 XNamespace ns = "http://www.compnay.com.tw/Invoice"; XElement el = new XElement(ns + "r", new XAttribute(XNamespace.Xmlns + "i", ns), new XElement(ns + "invoice", new XElement(ns + "invoiceNumber", "AB12345678"), new XElement(ns + "invoiceDate", DateTime.Now) ) );產生的 xml 結果如下
<i:r xmlns:i="http://www.compnay.com.tw/Invoice"> <i:invoice> <i:invoiceNumber>AB12345678</i:invoiceNumber> <i:invoiceDate>2008-09-02T08:52:11.4240786+08:00</i:invoiceDate> </i:invoice> </i:r>
沒有留言:
張貼留言