XML解析中的namespace初探
初學者在解析XML文件的時候最容易遇到的問題恐怕就是XML的namespace了,本文旨在對namespace做一個簡要的介紹。
namespace的意義無需多說,和C++,C#等高級語言一樣,XML同樣面臨大量文件放在一起的時候變量重名的問題,所以要用namespace把名字相同意義不同的變量隔離開。本文著重討論namespace的解析方法。
以下是一個簡單的XML文件:
<root>
?? <child id = ‘0’>
????? hello world
?? </child>
?? <child id='1'>
???? one
?? </child>
</root>
這個例子里面沒有namespace,大家初學XML時接觸的例子恐怕都是這樣的。這種例子具有誤導性,初學者解析出了hello world之后就興高采烈的拿同樣的程序去解析實際的XML文件,往往鎩羽而歸。下面是一段豆瓣API返回的XML文件
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"?xmlns:db="http://www.douban.com/xmlns/"?xmlns:gd="http://schemas.google.com/g/2005"?xmlns:opensearch="http://a9.com/-/spec/opensearchrss/1.0/">
? <id>http://api.douban.com/event/10069638</id>
? <title>Debugging the Web </title>
? <category scheme="http://www.douban.com/2007#kind"?term="http://www.douban.com/2007#event.salon"/>
? <author>
??? <link href="http://api.douban.com/people/1057620"?rel="self"/>
??? <link href="http://www.douban.com/people/aka/"?rel="alternate"/>
??? <link href="http://t.douban.com/icon/u1057620-16.jpg"?rel="icon"/>
??? name>胖胖的大頭魚</name>
??? <uri>http://api.douban.com/people/1057620</uri>
</author>
<db:attribute name="invite_only">no</db:attribute>
??? 看到這么多www就不想看直接跳過,然后看到熟悉的<author> </author>, 果斷套用上面例子的程序,一運行卻啥都得不到,問題到底出在哪?C#提供一大堆的XML類,XDocument, XReader, XPath, XmlDocument,是不是我現在用的這種類不給力啊,沒法確定只好亂試,一亂試一晚上就過去了。童鞋,我們還是靜下心來逐行看看吧。
?
<?xml version="1.0" encoding="UTF-8"?>這行沒看頭,看下面這里<entry xmlns="http://www.w3.org/2005/Atom"?,xmlns就是xml namespace的意思,這坑爹的http://www.w3.org/2005/Atom到底是個啥呢。再往后看,xmlns:db="http://www.douban.com/xmlns/"?,結合<db:attribute name="invite_only">no</db:attribute>這句話,可以理解了,db是一個namespace的簡稱,方便寫在元素的名字前面,這樣<db:attribute> 和 <attribute>, <gd:attribute>就不一樣了。這種簡稱可以在一個文檔里面區別變量,但是對大量的文檔還是不行,所以namespace還有一個全稱,就是這里的http://www.douban.com/xmlns/。這個全稱其實寫什么內容都行,對XML Parser來說都是當做字符串來處理的,但一來想名字比較麻煩,二來可以順道做個廣告,所以大家一般都用的網址。Parse的時候Parser根據全稱來區別變量,所以就算兩個文檔中都有<db:attribute>,只要全稱不一樣,都沒有問題。
?
這么說就比較清楚了,但那個http://www.w3.org/2005/Atom到底是個啥啊,連個簡稱都沒有。哎,意識到這個就對了,他的簡稱就是””,空串。這東西被稱為default namespace,那些看上去沒有前綴的都是在這個namespace下的。所以那個<author>不是裸的啊,人家其實是 <”http://www.w3.org/2005/Atom” : author> 所以裸的程序當然是解析不了的了。
?
那么該如何解析呢?這里提供一個樣例程序,希望對大家有幫助。這個代碼可以在WP7上運行。我還有一個版本用的XmlDocument,尼瑪WP7上木有這個類,坑爹的。。。
??????????? string file = @"C:\Users\v-menlin\Documents\Visual Studio 2010\Projects\test\test\test.xml";
??????????? XDocument doc = XDocument.Load( file );
??????????? //use following code to parse a string?
??????????? //XDocument doc = XDocument.Parse( string );
??????????? //對于XML文件中所有的沒加類似db:這種的元素,用下列方法
??????????? XNamespace d = @"http://www.w3.org/2005/Atom";
??????????? foreach ( XElement element in doc.Descendants( d + "title" ) )
??????????? {
??????????????? Console.WriteLine( element.Value );
??????????? }
??????????? //<author>下面包含了<link>,一下的例子還示例了如何讀取屬性。
??????????? foreach ( XElement element in doc.Descendants( d + "author" ) )
??????????? {
??????????????? foreach ( XElement inelement in element.Descendants( d + "link" ) )
??????????????? {
??????????????????? Console.WriteLine( inelement.Attribute( "href" ).Value );
??????????????????? Console.WriteLine( inelement.Attribute( "rel" ).Value );
??????????????? }
??????????? }
??????????? Console.WriteLine();
??????????? //對于加了冒號前綴的元素,使用下列代碼
??????????? XNamespace db = @"http://www.douban.com/xmlns/";
??????????? foreach ( XElement element in doc.Descendants( db + "attribute" ) )
??????????? {
??????????????? Console.WriteLine( element.Attribute( "name" ).Value );
??????????????? Console.WriteLine( element.Value );
??????????? }
??????????? //其實只是NameSpace的頭部換了一下。
??????????? //下面列出其他幾個常用頭部,直接換用。
??????????? XNamespace gd = @"http://schemas.google.com/g/2005";
??????????? XNamespace opensearch = @"http://a9.com/-/spec/opensearchrss/1.0/";
from:?http://www.cnblogs.com/meng-meng/archive/2011/09/26/2192355.html
總結
以上是生活随笔為你收集整理的XML解析中的namespace初探的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每一个有理想的程序员都应该读的一本书-《
- 下一篇: 使用 Chrome 开发者工具进行 Ja