C# 如何根据生成的.Net类或原始XSD中的元素/属性名从xml文件中提取字符串形式的值?
我有一个大型复杂的XSD集 我使用xsd.exe从这些xsd生成了C#类。当然,尽管生成的类中的大多数属性都是C# 如何根据生成的.Net类或原始XSD中的元素/属性名从xml文件中提取字符串形式的值?,c#,.net,xml,validation,serialization,C#,.net,Xml,Validation,Serialization,我有一个大型复杂的XSD集 我使用xsd.exe从这些xsd生成了C#类。当然,尽管生成的类中的大多数属性都是strings,但许多属性都是decimals、DateTimes、enums或bools,它们应该是这样的 现在,我有一些以正确的XML格式构造的未验证数据,但可能无法通过XSD验证,更不用说放入相关.Net对象的实例中了。例如,在这个阶段,据我们所知,应该是DateTime的元素的值可以是“ABC”-甚至不能解析为DateTime-更不用说其他关于maxLength或regex模式限
string
s,但许多属性都是decimal
s、DateTime
s、enum
s或bool
s,它们应该是这样的
现在,我有一些以正确的XML格式构造的未验证数据,但可能无法通过XSD验证,更不用说放入相关.Net对象的实例中了。例如,在这个阶段,据我们所知,应该是DateTime的元素的值可以是“ABC”-甚至不能解析为DateTime-更不用说其他关于maxLength或regex模式限制的字符串元素了。这些数据已经准备好传递给规则引擎,我们已经必须使所有内容都有效,包括根据其他数据项适当地进行缺省设置,等等
我知道如何使用System.Xml
中的各种类型按名称读取给定元素的字符串值。很明显,我可以手工编写代码,以按名称列出当前存在的所有元素——但如果XSD发生更改,则需要重新编写代码。我希望能够直接读取XSD或在生成的类上使用反射(必要时包括[System.Xml.Serialization.XmlTypeAttribute(TypeName=…])
等属性)要准确地找到如何递归地查询XML,直到任何给定元素的原始、未经验证的字符串版本传递到规则集,然后在规则使其生效后,将其放回强类型对象或放回XML副本,以便序列化到对象中
(我突然想到,另一种方法是以某种方式自动生成对象的“”版本(其中没有日期时间等;只有字符串),并将xml序列化到该版本中。我甚至疯狂地考虑使用xsd.exe生成的.cs文件,搜索/替换所有非字符串的枚举和基类型。)s到字符串,但必须有更好的方法。)
换句话说,是否有一种现有的通用方法可以从一些XML中提取XElement或属性值,这些XML如果被序列化,将与.Net类中的给定项相对应,而不实际序列化它?对不起,请自行回答,对不起,我的回答中缺少实际代码,但我还没有e我的雇主允许我分享这方面的实际代码。在这方面的工作,我会在这里更新时,有运动 我能够实现一个我称之为宽容的XML阅读器。与大多数XML反序列化不同,它首先使用反射来查看所需.Net类型的结构,然后尝试查找相关的元素并解释它们。任何额外的元素都会被忽略(因为它们从未被查找),未找到的任何元素都将被默认,找到的任何元素都将被进一步解释 以C#表示的主要方法签名如下:
public static T TolerantDeserializeIntoType<T>(
XDocument doc,
out List<string> messagesList,
out bool isFromSuppliedData,
XmlSchemaSet schemas = null,
bool tolerant = true)
public static T TolerantDeserializeIntoType(
XDocument doc,
输出列表消息列表,
我是从Supplieddata来的,
XmlSchemaSet schemase=null,
bool容差=真)
对它的典型调用可能如下所示:
List<string> messagesList;
bool defaultOnly;
SomeType result = TolerantDeserializeIntoType<SomeType>(someXDocument, out messagesList, out defaultOnly);
列表消息列表;
仅限布尔值;
SomeType结果=TolerantDeserializeIntoType(someXDocument,out messagesList,out defaultOnly);
(您可以使用var;在本例中,为了清楚起见,我只是显式地将类型放在那里)
这将获取anyXDocument(因此原始文档的唯一标准是格式良好),并从中生成指定类型的实例(本例中为SomeType)
请注意,即使XML中没有任何内容被识别,它也不会失败。新实例的所有属性/公共字段都将为null或默认值,MessageList将列出所有已完成的默认值,boolean out参数将为FALSE
完成所有工作的递归方法具有类似的签名,只是它采用XElement而不是XDocument,并且不采用schemaSet。(当前的实现也有一个显式bool来指示默认为false的递归调用。这是一种稍微脏一点的方式,允许它在抛出错误之前收集所有失败消息,如果容错为false;在未来的版本中,我将重构它,以仅公开一个没有该错误的版本,如果我甚至想XElement版本(完全公开):
公共静态T公差反序列化XelementInType(
参考XElement元素,
参考列表消息列表,
out bool是来自SuppliedValue,
布尔宽容=真,
bool recursiveCall=false)
它的工作原理、细节
从主调用开始,该调用包含XDocument和可选SchemaSet:
如果提供了将要编译的模式集(实际上,它还查找xsi:noNamespaceSchemaLocation),那么初始XDocument和schemaSet调用将运行标准XDocument.Validate()在提供的XDocument中,但这只收集任何已发出的验证错误回调。它不会引发异常,并且只有两个原因:
public static T TolerantDeserializeXElementIntoType<T>(
ref XElement element,
ref List<string> messagesList,
out bool isFromSuppliedValue,
bool tolerant = true,
bool recursiveCall = false)