现在位置首页 / 项目实战 /正文

C# Linq使用XDocument读取Xml文件并形成结构树数据(json)

作者: IT小兵 | 2014年5月5日| 热度:℃ | 评论: |参与:

在一篇文章中,[Jquery三级省市区县联动选择下拉菜单--自带全国完整xml数据]使用了xml配置全国的省市区数据。

数据结构是这样的:

<?xml version="1.0" encoding="gb2312" ?>
<address>
  <province name="北京市">
    <city name="北京辖区">
      <country name="东城区" />
      <country name="西城区" />
      <country name="崇文区" />
      <country name="宣武区" />
      <country name="朝阳区" />
      <country name="丰台区" />
      <country name="石景山区" />
      <country name="海淀区" />
      <country name="门头沟区" />
      <country name="房山区" />
      <country name="通州区" />
      <country name="顺义区" />
      <country name="昌平区" />
      <country name="大兴区" />
      <country name="怀柔区" />
      <country name="平谷区" />
    </city>
    <city name="北京辖县">
      <country name="密云县" />
      <country name="延庆县" />
    </city>
  </province>
  .....
  </address>

如何快速的读取xml数据,并按照xml数据结构,形成C#实体数据集合那?

我试了好几个方法都不是很灵活,其中有一个XML操作类,可以分享给大家:

 /// <summary>

    /// XmlHelper 的摘要说明

    /// </summary>

    public class XmlHelper

    {

        public XmlHelper()

        {

        }


        /// <summary>

        /// 读取数据

        /// </summary>

        /// <param name="path">路径</param>

        /// <param name="node">节点</param>

        /// <param name="attribute">属性名,非空时返回该属性值,否则返回串联值</param>

        /// <returns>string</returns>

        /**************************************************

         * 使用示列:

         * XmlHelper.Read(path, "/Node", "")

         * XmlHelper.Read(path, "/Node/Element[@Attribute='Name']", "Attribute")

         ************************************************/

        public static string Read(string path, string node, string attribute)

        {

            string value = "";

            try

            {

                XmlDocument doc = new XmlDocument();

                doc.Load(path);

                XmlNode xn = doc.SelectSingleNode(node);

                value = (attribute.Equals("") ? xn.InnerText : xn.Attributes[attribute].Value);

            }

            catch { }

            return value;

        }


        /// <summary>

        /// 插入数据

        /// </summary>

        /// <param name="path">路径</param>

        /// <param name="node">节点</param>

        /// <param name="element">元素名,非空时插入新元素,否则在该元素中插入属性</param>

        /// <param name="attribute">属性名,非空时插入该元素属性值,否则插入元素值</param>

        /// <param name="value">值</param>

        /// <returns></returns>

        /**************************************************

         * 使用示列:

         * XmlHelper.Insert(path, "/Node", "Element", "", "Value")

         * XmlHelper.Insert(path, "/Node", "Element", "Attribute", "Value")

         * XmlHelper.Insert(path, "/Node", "", "Attribute", "Value")

         ************************************************/

        public static void Insert(string path, string node, string element, string attribute, string value)

        {

            try

            {

                XmlDocument doc = new XmlDocument();

                doc.Load(path);

                XmlNode xn = doc.SelectSingleNode(node);

                if (element.Equals(""))

                {

                    if (!attribute.Equals(""))

                    {

                        XmlElement xe = (XmlElement)xn;

                        xe.SetAttribute(attribute, value);

                    }

                }

                else

                {

                    XmlElement xe = doc.CreateElement(element);

                    if (attribute.Equals(""))

                        xe.InnerText = value;

                    else

                        xe.SetAttribute(attribute, value);

                    xn.AppendChild(xe);

                }

                doc.Save(path);

            }

            catch { }

        }


        /// <summary>

        /// 修改数据

        /// </summary>

        /// <param name="path">路径</param>

        /// <param name="node">节点</param>

        /// <param name="attribute">属性名,非空时修改该节点属性值,否则修改节点值</param>

        /// <param name="value">值</param>

        /// <returns></returns>

        /**************************************************

         * 使用示列:

         * XmlHelper.Insert(path, "/Node", "", "Value")

         * XmlHelper.Insert(path, "/Node", "Attribute", "Value")

         ************************************************/

        public static void Update(string path, string node, string attribute, string value)

        {

            try

            {

                XmlDocument doc = new XmlDocument();

                doc.Load(path);

                XmlNode xn = doc.SelectSingleNode(node);

                XmlElement xe = (XmlElement)xn;

                if (attribute.Equals(""))

                    xe.InnerText = value;

                else

                    xe.SetAttribute(attribute, value);

                doc.Save(path);

            }

            catch { }

        }


        /// <summary>

        /// 删除数据

        /// </summary>

        /// <param name="path">路径</param>

        /// <param name="node">节点</param>

        /// <param name="attribute">属性名,非空时删除该节点属性值,否则删除节点值</param>

        /// <param name="value">值</param>

        /// <returns></returns>

        /**************************************************

         * 使用示列:

         * XmlHelper.Delete(path, "/Node", "")

         * XmlHelper.Delete(path, "/Node", "Attribute")

         ************************************************/

        public static void Delete(string path, string node, string attribute)

        {

            try

            {

                XmlDocument doc = new XmlDocument();

                doc.Load(path);

                XmlNode xn = doc.SelectSingleNode(node);

                XmlElement xe = (XmlElement)xn;

                if (attribute.Equals(""))

                    xn.ParentNode.RemoveChild(xn);

                else

                    xe.RemoveAttribute(attribute);

                doc.Save(path);

            }

            catch { }

        }

    }


后来,考虑一下Linq,不就是干这个事情的吗?Linq是从集合中查询对象,在linq to xml中的集合是通过XElement的Elements(),Elements(string name),以及Descendants、DescendantsAndSelf、Ancestors、AncestorsAndSelf的几个重载方法中获得。

获得XElement集合之后,可以通过XElement的Attribute(string name)方法获得元素的属性值,可以通过XElement的Value属性获得节点的文本值;使用linq就可以方便的做查询,做筛选排序了。

我们分析一下这个xml数据结构,

1、首先是取出address节点下面所有的province的name

2、下面取出province下面的所有city,形成集合

3、在取city的时候,取出country集合。

按照这个思路。读取xml数据并形成tree数据结构的Linq如下:

XmlDocument doc = new XmlDocument(); 
XDocument xdoc = XDocument.Load(context.Server.MapPath("/data/Area.xml"));         
var query = from item in xdoc.Element("address").Elements()
select new
{
name = item.Attribute("name").Value,
children = from cityitem in item.Elements()
select new
{
name = cityitem.Attribute("name").Value,
children = from countryitem in cityitem.Elements()
select new
{
name = countryitem.Attribute("name").Value 
}
}
};

这里用得是XDocument。XDocument和XmlDocument都可以用来操作XML文档,XDocument是.net 3.5为Linq to XML准备的轻量级Document对象,在功能上他和XmlDocument差不多,但是Linq to XML只能配合XDocument使用。XDocument提供了更舒服的创建xml方式。

方便在那里那?

 比如我们只取20条记录:

XmlDocument doc = new XmlDocument(); 
XDocument xdoc = XDocument.Load(context.Server.MapPath("/data/Area.xml"));         
var query =( from item in xdoc.Element("address").Elements()
select new
{
name = item.Attribute("name").Value,
children = from cityitem in item.Elements()
select new
{
name = cityitem.Attribute("name").Value,
children = from countryitem in cityitem.Elements()
select new
{
name = countryitem.Attribute("name").Value 
}
}
}).Take(20);

注意我加了(),并使用Take(20).

 


更多请参考:

http://www.cnblogs.com/yukaizhao/archive/2011/07/21/linq-to-xml.html

XDocument简单入门  

http://www.cnblogs.com/nsky/archive/2013/03/05/2944725.html 

 

点击阅读本文所属分类的更多文章: 项目实战 。和高手一起交流:346717337
友荐云推荐

未注明转发、原文均为本站原创。分享本文请注明 原文链接

给您更多信息和帮助

在这里您可以找到更多:

技术交流群:346717337 Jquery插件交流

投稿:suchso@vip.qq.com

承接:企业网站门户/微网站/微商城/CMS系统/微信公众号运营/业务咨询

抢天猫双11红包
推荐使用阿里云服务器
echarts教程系列
本月最热文章

微信扫一扫,徜徉悠嘻网,您的休闲乐园

微信公众号:快乐每一天

随机文章
标签

技术交流群:346717337

投稿:suchso@vip.qq.com

专业专注:企业网站门户/微网站/微商城/CMS系统/微信公众号运营/付费问题咨询