【发布时间】:2011-09-29 13:20:10
【问题描述】:
我必须对以下类进行 XML(反)序列化:
这给出了以下输出:
<ArrayOfPropertyFilter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PropertyFilter>
<AndOr>And</AndOr>
<LeftBracket>None</LeftBracket>
<Property>17</Property>
<Operator>Equal</Operator>
<Value xsi:type="xsd:string">lll</Value>
<RightBracket>None</RightBracket>
</PropertyFilter>
</ArrayOfPropertyFilter>
并且,在反序列化之后它给出
我怎样才能“告诉”序列化程序保持值“原样”,没有任何 XML 节点....(在具体情况下,值应该是“lll”而不是包含文本“lll”的 XMLNode)?
编辑
Bellow 是一个完整的 C# 示例。输出是
值为 = 'System.Xml.XmlNode[]'
using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
namespace WindowsFormsApplication13
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
PropertyFilter filter = new PropertyFilter();
filter.AndOr = "Jora";
filter.Value = "haha";
filter.Property = 15;
var xml = filter.SerializeToString();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
PropertyFilter cloneFilter = xmlDoc.Deserialize<PropertyFilter>();
Console.WriteLine("Value is = '{0}'", cloneFilter.Value);
}
}
public class PropertyFilter
{
public string AndOr { get; set; }
public string LeftBracket { get; set; }
public int Property { get; set; }
public string Operator { get; set; }
public object Value { get; set; }
public string RightBracket { get; set; }
}
public static class Utils
{
public static string SerializeToString(this object instance)
{
if (instance == null)
throw new ArgumentNullException("instance");
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
XmlSerializer serializer = new XmlSerializer(
instance.GetType(), null, new Type[0], null, null);
serializer.Serialize(sw, instance);
return sb.ToString();
}
public static T Deserialize<T>(this XmlDocument xmlDoc)
{
XmlNodeReader reader = new XmlNodeReader(xmlDoc.DocumentElement);
XmlSerializer serializer = new XmlSerializer(typeof(T));
object obj = serializer.Deserialize(reader);
T myT = (T)obj;
return myT;
}
}
}
编辑 2
为了强调安东的答案,第二个例子(更新了 Groo 的评论):
using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
namespace WindowsFormsApplication13
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
PropertyFilter filter = new PropertyFilter();
filter.AndOr = "Jora";
var obj = new Hehe();
obj.Behehe = 4526;
filter.Value = obj;
filter.Property = 15;
var xml = filter.SerializeToString();
PropertyFilter cloneFilter = xml.Deserialize<PropertyFilter>();
Console.WriteLine("Value is = '{0}'", cloneFilter.Value);
}
}
public class Hehe
{
public int Behehe { get; set; }
public override string ToString()
{
return string.Format("behehe is '{0}'", Behehe);
}
}
public class PropertyFilter
{
public string AndOr { get; set; }
public string LeftBracket { get; set; }
public int Property { get; set; }
public string Operator { get; set; }
//[XmlElement(typeof(Hehe))]
public object Value { get; set; }
public string RightBracket { get; set; }
}
public static class Utils
{
public static string SerializeToString(this object instance)
{
if (instance == null)
throw new ArgumentNullException("instance");
StringBuilder sb = new StringBuilder();
XmlSerializer serializer = new XmlSerializer(instance.GetType(), null, new Type[0], null, null);
using (StringWriter sw = new StringWriter(sb))
{
serializer.Serialize(sw, instance);
}
return sb.ToString();
}
public static T Deserialize<T>(this string xmlString)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader sr = new StringReader(xmlString))
{
return (T)serializer.Deserialize(sr);
}
}
}
}
【问题讨论】:
-
您期望的 XML 是什么?
-
@Seb 正如我所提到的,我希望我的反序列化值是对象(字符串)而不是 XmlNode。我演示Xml格式只是为了好奇,我不关心Xml,而是关心反序列化的值......
-
如果这个属性只包含字符串,那你为什么不把它的类型改成
string呢?但是如果它可以包含 anyobject,那么你显然需要将类型信息存储在某个地方。 -
@serhio:任何想要将您的 xml 反序列化为真正的 CLR 对象的代码都需要知道对象的确切类型才能创建它。这就是
XmlSerializer创建一个包含此信息的XmlNode的原因(在您的情况下,它有一个值为"xsd:string"的xsi:type 属性-这是您的对象的类型)。因此,无论如何,您都需要将此类型信息保存在某处,以便以后能够检索。正如@Seb 和我自己指出的那样,如果您想以某种特定方式存储此 type 信息,请在您的问题中进行描述。 -
@serhio:我觉得我们彼此不理解。你能回答这个问题吗:想象一下我刚刚给你发送了一个包含以下文本的 XML 文件:
<Value>10d</Value>。您启动应用程序并将文件反序列化为对象。 反序列化后您的 Value 属性将是什么类型,为什么?
标签: .net serialization xml-serialization