小小练习:对XML的处理

在博客园,在51CTO,CSDN上,有很多的大牛都写过关于Xml的解析,直接对网页进行抓取,我也看过一些,因为以前我也不知对Xml如何操作!

对于元素、结点、属性。。。的分析,你想更多了解,可以在网上搜一下!我是对上一篇中返回的Xml的简单的处理,谈不上解析,只是获取对应的数据!

很简单,写了个方法来获取数据!可以把这些方法放到,一个公共访问的类里,因为他多次使用,多出使用,封装的好处,避免代码重复,减少不必要的开发!

(注:别忘了加入对应的命名空间)

大概的流程,步骤:

<1>.先经过ReadXml(string xml)方法;
<2>.对xml处理,返回连接的字符串;
<3>.将字符串出入IDictionary<string, string> GetDic(string content)方法,得到对应的字典;
<4>.将字典传入User GetUser(IDictionary<string, string> dit)得到对应的类;(多对象也一样操作)

<1>.这是淘宝返回的XML:(这个和上一篇中的返回不一样,因为传入的参数不同和使用的用户昵称不同!)

View Code
单用户XML:

<?xml version="1.0" encoding="utf-8"?><user_get_response><user><buyer_credit><good_num>0</good_num><level>0</level><score>0</score><total_num>0</total_num></buyer_credit><created>2008-03-0723:28:36</created><nick>alipublic21</nick><sex>m</sex><type>B</type><user_id>65753077</user_id></user></user_get_response><!--vsandbox068049.cm4-->

多用户XML:

<?xml version="1.0" encoding="utf-8"?><users_get_response><users list="true"><user><buyer_credit><good_num>0</good_num><level>0</level><score>0</score><total_num>0</total_num></buyer_credit><created>2008-03-0723:28:36</created><nick>alipublic21</nick><sex>m</sex><type>B</type><user_id>65753077</user_id></user><user><buyer_credit><good_num>0</good_num><level>0</level><score>0</score><total_num>0</total_num></buyer_credit><created>2009-09-3011:19:03</created><nick>sandbox_c_1</nick><sex>f</sex><type>C</type><user_id>175978269</user_id></user></users></users_get_response><!--vsandbox068047.cm4-->

  

 public static string ReadXml(string xml)
        {
            StringBuilder builder = new StringBuilder();

            using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    { //注意:此处对于结点,在节点前加分号,将所有节点断开(使用根节点)                       
                        case XmlNodeType.EndElement: builder.Append(reader.Name + ";"); break;
                        case XmlNodeType.Text: builder.Append(reader.Value + "="); break;
                    }

                }
               
            }            
            return builder.ToString();
        }
<2>.这个方法写的很简单,那不是XML吗?把他当成文本,对结点进行控制,追加上字符';'和'=',使他变成可以控制的、可以调整的文本!

不过我是倒着取得值,因为下面会说!

对XML处理后的文本:

View Code
调用ReadXml(string xml)方法返回结果:

单用户:

0=good_num;0=level;0=score;0=total_num;buyer_credit;2008-03-0723:28:36=created;alipublic21=nick;m=sex;B=type;65753077=user_id;user;user_get_response;

多用户:
0=good_num;0=level;0=score;0=total_num;buyer_credit;2008-03-0723:28:36=created;alipublic21=nick;m=sex;B=type;65753077=user_id;user;0=good_num;0=level;0=score;0=total_num;buyer_credit;2009-09-3011:19:03=created;sandbox_c_1=nick;f=sex;C=type;175978269=user_id;user;users;users_get_response;

<3>.既然返回,我们可以调整的文本,就简单处理一下!将文本在解析,存入字典:

(才开始写的时候,对单用户和多用户分别解析,写了两个方法,后来优化一下,组合成一个方法!需传入类型,如:当前是对User类的处理,

将type,换成User即可!说说这个字典吧,前面的Key是存放个数,即有几个对象,如几个用户,单用户,多用户。后面的字典是存放对象的属性

我之所以倒着读是,先把前面的属性存入类中,当一遇到类的对象名,如:User.就把这个字典存好,index++,在存下一个,遍历文本!

对字符串的截取和字符串的Split(''),不说了!你可能会说,你是用字符';'和'='断开的,如果读的文本有同样的字符不就出错啦!是啊!

那就找一些不常用的字符作为断开字符,不要选常用的@、&。。。@是邮箱地址常用,碰到读取用户邮箱地址,那不就出错啦!)

        /// <summary>
        /// 对象集合写入字典(可以用多用户对象调试单用户)
        /// </summary>
        /// <param name="xml">XML文本</param>
        /// <param name="type">处理的类型,如User</param>
        /// <returns>多用户字典</returns>
        public static IDictionary<int, IDictionary<string, string>> GetDic(string xml, string type)
        {
            string content = ReadXml(xml).Trim().Replace("<span class=H>", null).Replace("</span>",null );
            dits = new Dictionary<int, IDictionary<string, string>>();
            IDictionary<string, string> dit = new Dictionary<string, string>();
            int index= 0;
            string[] arrays = content.Split(';');
            foreach (string item in arrays)
            {
                if (item == type)//最好是,根节点
                {
                    if (dit.Count > 0)
                    { index++; dits.Add(index, dit); dit = new Dictionary<string, string>(); }
                }
                if (!string.IsNullOrEmpty(item))
                {
                    string[] param = item.Split('=');

                    if (!string.IsNullOrEmpty(param[0]))//注意:必须key值不为空,但value值可以为空
                    {
                        dit.Add(param[param.Length - 1], param[0]);
                    }
                }
            }
            return dits;
        }


<4>.字典的样式没法看,只有调试好看一些,我们总不能使用字典的数据吧!(当然,也有直接度XML的数据或直接读字典的数据)

我们做的是建一个类来存放对应的数据,可以读取和写入,User类!这样有需要将字典读到类里,是不是很麻烦,现在还很菜,用的不是很好!

这次给一个较全的,对私有的信息一起解析:

View Code
using System;
using System.Collections.Generic;
using Common;
using Model;

namespace BLL
{
publicclass UsersBLL
{
///<summary>
/// 获取用户集合列表
///</summary>
///<param name="xml"></param>
///<returns></returns>
publicstatic List<User> GetUsers(string xml)
{
List
<User> users =new List<User>();
IDictionary
<int, IDictionary<string, string>> dits = ReadXmlHelper.GetDic(xml, "user");
foreach (IDictionary<string, string> dic in dits.Values)
{
User user
=new User();
UserCredit credit
=new UserCredit();
Location location
=new Location();

foreach (KeyValuePair<string, string> kvp in dic)
{
bool bo;
string key = kvp.Key;
string value = kvp.Value;
switch (key)
{
case"user_id": user.UserId = value; break;
case"uid": user.Uid = value; break;
case"nick": user.Nick = value; break;
case"avatar": user.Avatar = value; break;
case"alipay_no": user.AlipayNo = value; break;
case"birthday": user.Birthday = value; break;
case"email": user.Email = value; break;
case"created": user.Created = value; break;
case"last_visit": user.Last_Visit = value; break;
case"alipay_account": user.AlipayAccount = value; break;
case"sex": if (value =="m") { user.Sex =""; } else { user.Sex =""; } break;

case"zip": location.Zip = value; break;
case"address": location.Address = value; break;
case"city": location.City = value; break;
case"state": location.Sate = value; break;
case"country": location.Country = value; break;
case"district": location.District = value; break;
case"location": user.Location = location; break;

case"level": credit.Level = Convert.ToInt64(value); break;
case"score": credit.Score = Convert.ToInt64(value); break;
case"total_num": credit.TotalNum = Convert.ToInt64(value); break;
case"good_num": credit.GoodNum = Convert.ToInt64(value); break;
case"seller_credit": user.SellerCredit = credit; break;
case"buyer_credit": user.Buyer_Credit = credit; break;
case"alipay_bind":
if (value =="bind")
{
user.Alipay_Bind
="已绑定";
}
else
{
user.Alipay_Bind
="未绑定";
}
break;
case"has_shop": bo = Convert.ToBoolean(value);
if (bo)
{
user.Has_Shop
="开过店铺";
}
else
{
user.Has_Shop
="未开过店铺";
}
break;
case"consumer_protection": bo = Convert.ToBoolean(value);
if (bo)
{
user.ConsumerProtection
="已参加消保";
}
else
{
user.ConsumerProtection
="未参加消保";
}
break;
case"promoted_type":
if (value =="authentication")
{
user.PromotedType
="实名认证";
}
else
{
user.PromotedType
="没有实名认证";
}
break;
case"magazine_subscribe": bo = Convert.ToBoolean(value);
if (bo)
{
user.Magazine_Subscribe
="已订阅淘宝天下杂志";
}
else
{
user.Magazine_Subscribe
="未订阅淘宝天下杂志";
}
break;
default: break;
}
}
users.Add(user);
}
return users;
}
}
}

存入类,就可以在有的地方调用啦!他是一个有数据的集合体,有内容的对象实体,有血有肉,不是空架子,不是空壳,不是声明!呵呵。。。

posted @ 2011-08-18 19:51  SanMaoSpace  阅读(496)  评论(0编辑  收藏  举报