捕获架构信息验证的XDocument
时,这是类似于此问题C# Get schema information when validating xml捕获架构信息验证的XDocument
不过,我与LINQ目的一个XDocument工作。
我正在读取/解析一组CSV文件并转换为XML,然后根据XSD模式验证XML。
我想捕捉与元素值相关的特定错误,生成更多用户友好的消息,并将它们返回给用户,以便可以更正输入数据。我希望在输出数据中包含的项目之一是某些模式信息(例如数字类型的可接受值的范围)。
在我目前的方法中(我愿意改变),除了模式信息之外,我能够捕捉到我需要的所有东西。
我试过访问SourceSchemaObject
中ValidationEventArgs
验证事件处理程序的参数,但始终为空。我也尝试了XElement的GetSchemaInfo
,而且看起来也是空的。
我正在使用RegEx来识别我想捕获的特定验证错误,并通过验证事件处理程序的发件人参数从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);
线只是一个占位符还不存在这种方法的目的是做三件事情:
通过
args.Message
使用正则表达式确定具体的验证错误(这个已经工作,我已经测试过,我打算使用模式)抓住从涉及到具体的XElement的的XDocument导致该错误的属性值(如原始CSV中的行号和列号)
如果可用模式信息可用,则可将字段类型和限制添加到输出消息中。
对于任何未来阅读此问题的人,尽管与原先建议的方式稍有不同,但我仍设法解决了我的问题。
我遇到的第一个问题是,XElement的ValidationEventArgs和GetSchemaInfo扩展方法中的SchemaInfo都是null。我解决了这个问题,就像我最初链接的问题一样。
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
}
这样看来,该模式的信息是不添加到X对象,直到确认后回调,因此,如果您尝试访问它在验证回调的中间,这将是空的,但如果您捕捉元素,然后在Validate方法完成后访问它,它不会为空。
但是,这又开辟了另一个问题。 SchemaInfo对象模型没有很好的文档记录,我无法解析出来找到我需要的东西。
我在问我原来的问题后发现这question。被接受的答案链接到一个非常棒的blog帖子,该帖子对SchemaInfo对象模型进行了细分。我花了一些工作来改进代码以适应我的目的,但它很好地阐释了如何为任何XmlReader元素(我可以更改为使用XObject)获取SchemaInfo。