在验证XDocument时捕获模式信息
本文关键字:模式 信息 验证 XDocument | 更新日期: 2023-09-27 18:11:57
这个问题类似于c#验证xml时获取模式信息
然而,我正在使用一个用于LINQ目的的XDocument。
我正在读取/解析一组CSV文件并将其转换为XML,然后根据XSD模式验证XML。
我想捕获与元素值相关的特定错误,生成更用户友好的消息,并将它们返回给用户,以便可以纠正输入数据。我想在输出数据中包含的一项是一些模式信息(例如数字类型的可接受值范围)。
在我目前的方法中(我愿意改变),我能够捕获除了模式信息之外的所有我需要的东西。
我已经尝试访问验证事件处理程序的ValidationEventArgs
参数中的SourceSchemaObject
,但这始终是空的。我还尝试了XElement的GetSchemaInfo
,这似乎也是null。
我使用RegEx来识别我想要捕获的特定验证错误,并通过验证事件处理程序的sender参数从XElement获取数据。我想过将模式转换为XDocument并通过LINQ抓取我需要的东西,但在我看来,应该有一个更好的选择
这是我当前的验证方法:
private List<String> this.validationWarnings;
private XDocument xDoc;
private XmlSchemaSet schemas = new XmlSchemaSet();
public List<String> Validate()
{
this.validationWarnings = new List<String>();
// the schema is read elsewhere and added to the schema set
this.xDoc.Validate(this.schemas, new ValidationEventHandler(ValidationCallBack), true);
return validationWarnings
}
这是我的回调方法:
private void ValidationCallBack(object sender, ValidationEventArgs args)
{
var element = sender as XElement;
if (element != null)
{
// this is a just a placeholder method where I will be able to extract the
// schema information and put together a user friendly message for specific
// validation errors
var message = FieldValidationMessage(element, args);
// if message is null, then the error is not one one I wish to capture for
// the user and is related to an invalid XML structure (such as missing
// elements or incorrect order). Therefore throw an exception
if (message == null)
throw new InvalidXmlFileStructureException(args.Message, args.Exception);
else
validationWarnings.Add(message);
}
}
var message = FieldValidationMessage(element, args);
行在我的回调方法只是一个占位符,还不存在,这个方法的意图是做3件事:
通过在
args.Message
上使用RegEx识别特定的验证错误(这已经工作了,我已经测试了我计划使用的模式)从XDocument中获取与导致错误的特定XElement相关的属性值(例如原始CSV中的行号和列号)
如果schema信息可用,获取schema信息,以便将字段类型和限制添加到输出消息中。
对于将来看到这个问题的人,我设法解决了我的问题,尽管与我最初提出的方法略有不同。
我遇到的第一个问题是,XElement的ValidationEventArgs和GetSchemaInfo扩展方法中的SchemaInfo都为空。我以同样的方式解决了这个问题,我原来链接....
List<XElement> errorElements = new List<XElement>();
serializedObject.Validate((sender, args) =>
{
var exception = (args.Exception as XmlSchemaValidationException);
if (exception != null)
{
var element = (exception.SourceObject as XElement);
if (element != null)
errorElements.Add(element);
}
});
foreach (var element in errorElements)
{
var si = element.GetSchemaInfo();
// do something with SchemaInfo
}
似乎直到验证回调之后才将Schema信息添加到XObject中,因此如果您试图在验证回调的中间访问它,它将为空,但是如果您捕获元素,然后在Validate方法完成后访问它,它将不是空。
然而,这又引出了另一个问题。SchemaInfo对象模型没有很好的文档化,我在解析它以找到我需要的东西时遇到了麻烦。
我问了我原来的问题后发现了这个问题。被接受的答案链接到一篇非常棒的博客文章,该文章详细介绍了SchemaInfo对象模型。我花了一点时间来改进代码以满足我的目的,但是它很好地说明了如何获得任何XmlReader元素的SchemaInfo(我可以将其更改为与XObject一起工作)。