最新类库,请访问https://github.com/twtyypmb/KeyValueEx
对于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;
}
欢迎指正,希望对大家有用