【发布时间】:2015-06-02 17:34:25
【问题描述】:
当我从 Xml 反序列化对象时,如何检查我的 xml 中是否缺少属性或元素?
XmlSerializer 用默认值填充缺失值,但我如何知道它是默认值还是 Xml 中缺失的值?
我必须知道这一点,因为如果我发布了我的程序的新版本并向我的对象添加了值,我想向用户显示一个带有新(缺失)值的提示。他必须知道情况。
[Serializable]
public class Dummy
{
public int MyInteger { get; set; }
public string MyString { get; set; }
public double MyDouble { get; set; }
public bool MyBool { get; set; }
public Dummy()
{
//Missing values in the xml would filled up with these values
MyInteger = default(int);
MyString = default(string);
MyDouble = default(double);
MyBool = default(bool);
}
}
class Program
{
static void Main(string[] args)
{
XmlSerializer serializer = new XmlSerializer(typeof(Dummy));
Dummy dummy = new Dummy(){ MyInteger = 1, MyBool = false, MyDouble = 3.4, MyString="dummy"};
StringBuilder sb = new StringBuilder();
using(StringWriter writer = new StringWriter(sb))
serializer.Serialize(writer, dummy);
/*sb contains:
* <?xml version="1.0" encoding="utf-16"?>
* <Dummy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
* <MyInteger>1</MyInteger>
* <MyString>dummy</MyString>
* <MyDouble>3.4</MyDouble>
* <MyBool>false</MyBool>
* </Dummy>
*/
//xml without MyDouble
string xml = @" <Dummy>
<MyInteger>1</MyInteger>
<MyString>dummy</MyString>
<MyBool>false</MyBool>
</Dummy>";
Dummy readDummy;
using (StringReader reader = new StringReader(xml))
readDummy = (Dummy)serializer.Deserialize(reader);
/*readDummy contains:
* MyInteger = 1,
* MyString = "dummy",
* MyDouble = 0,
* MyBool = false
*/
}
}
更新
感谢 Yeldar Kurmangaliyev 进行模式验证。 我当前的问题是 Schema-Validator 引发的异常让我只能访问 MyBool 而不是缺失值 MyDouble。 Exception-Message 包含属性 MyDouble 的名称,但我应该从 Exception-Message 中提取属性名称吗?感觉很脏。
这是更新后的代码:
[Serializable]
public class Dummy
{
public int MyInteger { get; set; }
public string MyString { get; set; }
public double MyDouble { get; set; }
public bool MyBool { get; set; }
public Dummy()
{
//Missing values in the xml would filled up with these values
MyInteger = default(int);
MyString = default(string);
MyDouble = default(double);
MyBool = default(bool);
}
}
class Program
{
static void Main(string[] args)
{
XmlSerializer serializer = new XmlSerializer(typeof(Dummy));
string xml = @" <Dummy>
<MyInteger>1</MyInteger>
<MyString>dummy</MyString>
<MyBool>false</MyBool>
</Dummy>";
Dummy readDummy;
XmlReaderSettings settings = new XmlReaderSettings() { ValidationType = ValidationType.Schema };
settings.Schemas.Add(GetXmlSchemas(typeof(Dummy)).First());
settings.ValidationEventHandler += (s, e) =>
{
//I got an exception with the sender "MyBool". How I can reach the variable "MyDouble" which is missing?
};
using (StringReader reader = new StringReader(xml))
using (XmlReader xmlReader = XmlReader.Create(reader, settings))
readDummy = (Dummy)serializer.Deserialize(xmlReader);
}
public static XmlSchemas GetXmlSchemas(Type type)
{
var schemas = new XmlSchemas();
var exporter = new XmlSchemaExporter(schemas);
var mapping = new XmlReflectionImporter().ImportTypeMapping(type);
exporter.ExportTypeMapping(mapping);
return schemas;
}
}
【问题讨论】:
-
如果没有
MyDouble,您希望如何生成xml? -
Xml 是在旧版本的程序中生成的,其中不存在 MyDouble。在新版本中我添加了 MyDouble,但它在旧的 xml 文件中不存在。或者只是假设用户已经从 XML 文件中删除了一个元素。
-
使元素
Nullable在Deserialization期间不应包含默认值。 -
“使元素可空”是什么意思?如果我将
MyDouble的定义更改为double? MyDouble没有效果。默认值(在构造函数中)是必需的。
标签: c# xmlserializer