Windows Phone 解析带有命名空间的xml数据

本文介绍XML命名空间的基本概念,通过实例解析如何正确处理带有命名空间的XML文件,并提供C#代码示例。

这个例子里面没有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/;

 

我的例子:

string a = "<GetHotelRoomQtyResponse xmlns=\"http://te.org/\">"
+ "<GetHotelRoomQtyResult>"
+ "<rmTypes>"
+ "<RmType>"
+ "<CName>标准单人房</CName>"
+ "<status>1</status>"
+ "</RmType>"
+ "</rmTypes>"
+ "</GetHotelRoomQtyResult>"
+ "</GetHotelRoomQtyResponse>";

StringReader stream = new StringReader(a);
XDocument xdoc = XDocument.Load(stream);
MessageBox.Show(xdoc.Root.Value.ToString());

XNamespace d = @"http://tem.org/";
foreach (XElement element in xdoc.Descendants(d + "CName"))
{
MessageBox.Show(element.Value);
}
XNamespace d = @"http://tempuri.org/";
StringReader stream = new StringReader(e.Result);
XDocument xdoc = XDocument.Load(stream);
hotelQty = from query in xdoc.Descendants(d+"RmType")
                       select new HotelQty
                      {
                          CName = (string)query.Element(d+"CName"),                      
                      };
            foreach (var item in hotelQty)
            {
                MessageBox.Show(item.CName);
            }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值