当我从Xml反序列化一个Object时,如何检查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;
}
}
答案 0 :(得分:1)
您可以使用XmlReaderSettings
课程来初始化XmlReader
并使用StringReader
。但是,您将需要XSD架构。
这是在反序列化时验证XML的正确方法
看看XmlReaderSettings。也许,你会发现一种更简单的方法:)
string xml = @" <Dummy>
<MyInteger>1</MyInteger>
<MyString>dummy</MyString>
<MyBool>false</MyBool>
</Dummy>";
Dummy readDummy;
XmlSchemaSet schemas = null; // here is your schema
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(schemas);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += (s, e) =>
{
throw e.Exception; // Here you go
};
using (StringReader reader = new StringReader(xml))
using (XmlReader xmlReader = XmlReader.Create(reader, settings))
readDummy = (Dummy)serializer.Deserialize(xmlReader);