小小练习:对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:(这个和上一篇中的返回不一样,因为传入的参数不同和使用的用户昵称不同!)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
单用户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处理后的文本:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
调用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类!这样有需要将字典读到类里,是不是很麻烦,现在还很菜,用的不是很好!
这次给一个较全的,对私有的信息一起解析:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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;
}
}
}
存入类,就可以在有的地方调用啦!他是一个有数据的集合体,有内容的对象实体,有血有肉,不是空架子,不是空壳,不是声明!呵呵。。。