xml对象转换成Dictionary或者list

对于xml对象有时候要转换成字典对象更容易读取和操作,而字典对象有个问题,就是不能有重复的键,所以对于这种情况就用list来代替,以下为代码

        /// <summary>
        /// xml文档对象转换到Dictionary<string,object>或list
        /// 拥有重复名称子节点的节点会被转换成list,而忽略子节点的名称
        /// </summary>
        /// <param name="xml_doc">xml文档对象</param>
        /// <param name="dso">保存Dictionary的对象</param>
        public static void XmlToDictionaryOrList( XmlDocument xml_doc,object dso )
        {
            if( xml_doc == null || xml_doc.DocumentElement == null || dso == null )
            {
                return;
            }

            XmlToDictionaryOrListWithOutAttributes( xml_doc.DocumentElement,dso );
        }

        /// <summary>
        /// 转换当前节点为字典或list
        /// </summary>
        /// <param name="xn"></param>
        /// <param name="dso"></param>
        private static void XmlToDictionaryOrListWithOutAttributes( XmlNode xn,object dso )
        {

            XmlNodeList xnl = xn.ChildNodes;
            List<object> list = null;
            Dictionary<string,object> dic = null;

            if( dso is Dictionary<string,object> )
            {
                dic = dso as Dictionary<string,object>;
            }
            else
            {
                list = dso as List<object>;
            }

            object temp = null;


            // 如果没有子节点了,退出递归的条件
            // 后一个条件是为了忽略xml的强制数据条件<![CDATA[...]]>,不把它当作子节点处理
            if( xnl.Count == 0 || xn.InnerText == xn.InnerXml )
            {
                //如果本节点是字典类型
                if( dic != null )
                {
                    // 添加键值对
                    dic.Add( xn.Name,xn.InnerText );
                }
                // 如果本节点是list类型,直接添加值,忽略键
                else if( list != null )
                {
                    list.Add( xn.InnerText );
                }
                else
                {
                    throw new Exception( "转换失败" );
                }

                return;
            }
            else
            {
                // 如果有重复的子节点
                if( XmlNodeHasDuplicateChild( xn ) )
                {
                    // 装子节点的对象为list
                    temp = new List<object>();
                }
                else
                {
                    temp = new Dictionary<string,object>();
                }

                if( dic != null )
                {
                    // 以空字典添加节点
                    dic.Add( xn.Name,temp );
                }
                else if( list != null )
                {

                    list.Add( temp );
                }
                else
                {
                    throw new Exception( "转换失败" );
                }

            }


            // 子节点递归
            for( int i = 0; i < xnl.Count; i++ )
            {
                XmlToDictionaryOrListWithOutAttributes( xnl[i],temp );
            }
        }


        /// <summary>
        /// XmlNode下有无重复子节点
        /// </summary>
        /// <param name="xn"></param>
        /// <returns></returns>
        public static bool XmlNodeHasDuplicateChild( XmlNode xn )
        {

            Dictionary<string,string> temp = new Dictionary<string,string>();

            for( int i = 0; i < xn.ChildNodes.Count; i++ )
            {
                if( temp.ContainsKey( xn.ChildNodes[i].Name ) )
                {
                    return true;
                }
                temp[xn.ChildNodes[i].Name] = "呵呵";
            }

            return false;
        }



第一个是入口函数,第二个是节点递归,第三个是辅助函数,对于这个转换函数有个地方要注意,某个节点的子节点一旦有相同名称,不管是全部相同,还是部分相同,都会把这个节点变成list,不过部分相同的情况应该比较少吧,谁会设计这种蛋疼的格式呢?

欢迎指正,希望对大家有用

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇