对象与XML的互相转化,大家可以试下

danjiewu 2007-01-19 06:30:25
如果用XMLSerializer不行的话,可以试试这个。比较适合比较小的对象,数据量大或者结构复杂的要慎用。测试下有什么问题。

========================================================================

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Collections;

namespace System
{
public static class XMLConvert
{
private const string tag_reference = "ref";
private const string tag_type = "type";
private const string tag_param = "params";
private const char char_left = '(';
private const char char_right = ')';

private static Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

public static string ToXML(object o)
{
return ToXML("class", o);
}

public static string ToXML(string name, object o)
{
StringBuilder stringBuilder = new StringBuilder();
XmlTextWriter xmlWriter = new XmlTextWriter(new StringWriter(stringBuilder));
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteStartDocument();
ToXML(name, o, xmlWriter, new Hashtable());
xmlWriter.WriteEndDocument();
return stringBuilder.ToString();
}

public static object ToObject(string strXML)
{
XmlDocument xml = new XmlDocument();
xml.LoadXml(strXML);
return ToObject(xml);
}

public static object ToObject(XmlDocument xml)
{
Hashtable refMap = new Hashtable(xml.ChildNodes.Count * 4);
object value = ToObject(xml.LastChild, refMap);
return value;
}

private static void ToXML(string name, object value, XmlWriter xmlWriter, Hashtable refMap)
{
xmlWriter.WriteStartElement(name);
if (value != null)
{
if (refMap.ContainsKey(new Ref(value)))
{
xmlWriter.WriteAttributeString(tag_reference, refMap[new Ref(value)].ToString());
}
else
{
Type type = value.GetType();
TypeToXML(type, xmlWriter);
if (!type.IsValueType)
{
xmlWriter.WriteAttributeString(tag_reference, refMap.Count.ToString());
refMap.Add(new Ref(value), refMap.Count);
}

if (type.IsPrimitive || type.Equals(typeof(string)))
{
xmlWriter.WriteString(Convert.ToString(value));
}
else if (type.IsArray)
{
foreach (object subvalue in (value as Array))
{
ToXML("element", subvalue, xmlWriter, refMap);
}
}
else
{
ToXML(type, value, xmlWriter, refMap);
}
}
}
xmlWriter.WriteEndElement();
}
...全文
264 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
cychris 2008-08-08
  • 打赏
  • 举报
回复
mark
王集鹄 2008-08-08
  • 打赏
  • 举报
回复


代码着色好些,这个排版乱了。。。。
亦风亦尘 2008-08-08
  • 打赏
  • 举报
回复
up
w4585 2008-07-22
  • 打赏
  • 举报
回复
MARK
sheyj 2008-07-22
  • 打赏
  • 举报
回复
这个很好用,谢谢!
danjiewu 2007-01-19
  • 打赏
  • 举报
回复
//接上面

private static Type GetType(string name)
{
int index1 = name.IndexOf(char_left);
int index2 = name.LastIndexOf(char_right);
if (index1 < 0)
{
Type type = Type.GetType(name);
if (type == null)
{
foreach (Assembly assembly in assemblies)
{
type = assembly.GetType(name);
if (type != null) break;
}
}
return type;
}
else
{
return GetGenericType(GetType(name.Substring(0, index1)), name.Substring(index1 + 1, index2 - index1 - 1));
}
}

private static FieldInfo GetField(Type type, string name)
{
FieldInfo field = null;
while (field == null && type != null)
{
field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
type = type.BaseType;
}
return field;
}

private static Type GetGenericType(Type type, string param)
{
string[] paramNames = Split(param, ',', char_left, char_right);
Type[] paramTypes = new Type[paramNames.Length];
for (int i = 0; i < paramNames.Length; i++)
{
paramTypes[i] = GetType(paramNames[i]);
}
return type.MakeGenericType(paramTypes);
}

private static string[] Split(string str, char separator, char left, char right)
{
List<string> results = new List<string>(str.Length / 10);
int start = 0;
for (int i = 0, stack = 0; i < str.Length; i++)
{
if (str[i] == separator && stack == 0)
{
results.Add(str.Substring(start, i - start));
start = i + 1;
}
if (str[i] == left) stack++;
if (str[i] == right) stack--;
}
if (start < str.Length) results.Add(str.Substring(start));
return results.ToArray();
}

class Ref
{
private object value = null;

public Ref(object o)
{
value = o;
}

public override bool Equals(object obj)
{
if (obj is Ref && ReferenceEquals(value, (obj as Ref).value)) return true;
else return false;
}

public override int GetHashCode()
{
if (value != null) return value.GetHashCode();
else return 0;
}
}
}
}
danjiewu 2007-01-19
  • 打赏
  • 举报
回复
//接上面

private static void ToXML(Type type, object value, XmlWriter xmlWriter, Hashtable refMap)
{
if (type == null || type.Equals(typeof(object))) return;
FieldInfo[] fields = type.GetFields(BindingFlags.GetField | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo field in fields)
{
ToXML(field.Name, field.GetValue(value), xmlWriter, refMap);
}
ToXML(type.BaseType, value, xmlWriter, refMap);
}

private static void TypeToXML(Type type, XmlWriter xmlWriter)
{
if (type.IsGenericType)
{
Type genericType = type.GetGenericTypeDefinition();
xmlWriter.WriteAttributeString(tag_type, genericType.FullName);
Type[] genericArguments = type.GetGenericArguments();
xmlWriter.WriteAttributeString(tag_param, ToParamsName(genericArguments));
}
else
{
xmlWriter.WriteAttributeString(tag_type, type.FullName);
}
}

private static string ToParamsName(Type[] genericArguments)
{
string[] names = new string[genericArguments.Length];
for (int i = 0; i < genericArguments.Length; i++)
{
if (genericArguments[i].IsGenericType)
names[i] = genericArguments[i].GetGenericTypeDefinition().FullName + char_left + ToParamsName(genericArguments[i].GetGenericArguments()) + char_right;
else
names[i] = genericArguments[i].FullName;
}
return String.Join(", ", names);
}

private static object ToObject(XmlNode node, Hashtable refMap)
{
if (node == null || node.Attributes.Count == 0) return null;
if (node.Attributes[tag_reference] != null && refMap[Int32.Parse(node.Attributes[tag_reference].Value)] != null) return refMap[Int32.Parse(node.Attributes[tag_reference].Value)];

Type type = GetType(node.Attributes[tag_type].Value);
if (type.IsGenericTypeDefinition)
{
string paramName = node.Attributes[tag_param].Value;
type = GetGenericType(type, paramName);
}

object value = null;
if (type.Equals(typeof(IntPtr)))
{
value = (IntPtr)Convert.ToInt32(node.InnerText);
}
else if (type.IsPrimitive || type.Equals(typeof(string)))
{
value = Convert.ChangeType(node.InnerText, type);
}
else if (type.IsArray)
{
value = Array.CreateInstance(type.GetElementType(), node.ChildNodes.Count);
}
else
{
value = FormatterServices.GetUninitializedObject(type);
}

if (node.Attributes[tag_reference] != null) refMap[Int32.Parse(node.Attributes[tag_reference].Value)] = value;

if (type.Equals(typeof(IntPtr))) { }
else if (type.IsPrimitive || type.Equals(typeof(string))) { }
else if (type.IsArray)
{
for (int i = 0; i < node.ChildNodes.Count; i++)
{
(value as Array).SetValue(ToObject(node.ChildNodes[i], refMap), i);
}
}
else
{
foreach (XmlNode xmlnode in node.ChildNodes)
{
FieldInfo field = GetField(type, xmlnode.Name);
field.SetValue(value, ToObject(xmlnode, refMap));
}
}
return value;
}

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧