专注网页设计制作教程: http://www.update8.com

XML解析中的namespace初探

时间:2011-09-27 09:18点击: 次 【

初学者在解析XML文件的时候最容易遇到的问题恐怕就是XML的namespace了,本文旨在对namespace做一个简要的介绍。

namespace的意义无需多说,和C++,C#等高级语言一样,XML同样面临大量文件放在一起的时候变量重名的问题,所以要用namespace把名字相同意义不同的变量隔离开。本文着重讨论namespace的解析方法。

以下是一个简单的XML文件:

  1. <root> 
  2.    <child id = ‘0’> 
  3.       hello world 
  4.    </child> 
  5.    <child id='1'> 
  6.      one 
  7.    </child> 
  8. </root> 

这个例子里面没有namespace,大家初学XML时接触的例子恐怕都是这样的。这种例子具有误导性,初学者解析出了hello world之后就兴高采烈的拿同样的程序去解析实际的XML文件,往往铩羽而归。下面是一段豆瓣API返回的XML文件

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <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/"> 
  3.   <id>http://api.douban.com/event/10069638</id> 
  4.   <title>Debugging the Web </title> 
  5.   <category scheme="http://www.douban.com/2007#kind" term="http://www.douban.com/2007#event.salon"/> 
  6.   <author> 
  7.     <link href="http://api.douban.com/people/1057620" rel="self"/> 
  8.     <link href="http://www.douban.com/people/aka/" rel="alternate"/> 
  9.     <link href="http://t.douban.com/icon/u1057620-16.jpg" rel="icon"/> 
  10.     name>胖胖的大头鱼</name> 
  11.     <uri>http://api.douban.com/people/1057620</uri> 
  12. </author> 
  13. <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上木有这个类,坑爹的。。。     

  1. string file = @"C:\Users\v-menlin\Documents\Visual Studio 2010\Projects\test\test\test.xml"; 
  2.           XDocument doc = XDocument.Load( file ); 
  3.           //use following code to parse a string 
  4.           //XDocument doc = XDocument.Parse( string ); 
  5.  
  6.           //对于XML文件中所有的没加类似db:这种的元素,用下列方法 
  7.           XNamespace d = @"http://www.w3.org/2005/Atom"; 
  8.           foreach ( XElement element in doc.Descendants( d + "title" ) ) 
  9.           { 
  10.               Console.WriteLine( element.Value ); 
  11.           } 
  12.           //<author>下面包含了<link>,一下的例子还示例了如何读取属性。 
  13.           foreach ( XElement element in doc.Descendants( d + "author" ) ) 
  14.           { 
  15.               foreach ( XElement inelement in element.Descendants( d + "link" ) ) 
  16.               { 
  17.                   Console.WriteLine( inelement.Attribute( "href" ).Value ); 
  18.                   Console.WriteLine( inelement.Attribute( "rel" ).Value ); 
  19.               } 
  20.           } 
  21.  
  22.           Console.WriteLine(); 
  23.           //对于加了冒号前缀的元素,使用下列代码 
  24.           XNamespace db = @"http://www.douban.com/xmlns/"; 
  25.           foreach ( XElement element in doc.Descendants( db + "attribute" ) ) 
  26.           { 
  27.               Console.WriteLine( element.Attribute( "name" ).Value ); 
  28.               Console.WriteLine( element.Value ); 
  29.           } 
  30.           //其实只是NameSpace的头部换了一下。 
  31.           //下面列出其他几个常用头部,直接换用。 
  32.           XNamespace gd = @"http://schemas.google.com/g/2005"; 
  33.           XNamespace opensearch = @"http://a9.com/-/spec/opensearchrss/1.0/" 
------分隔线----------------------------
相关文章