validationXDocument时捕获架构信息

这类似于这个问题C#在validationxml时获取模式信息

但是,我正在使用XDocument进行LINQ目的。

我正在读取/解析一组CSV文件并转换为XML,然后根据XSD架构validationXML。

我想捕获与元素值相关的特定错误,生成更加用户友好的消息,并将它们返回给用户,以便可以更正输入数据。 我想在输出数据中包含的项目之一是一些架构信息(例如数字类型的可接受值的范围)。

在我目前的方法(我愿意改变)中,除了架构信息之外,我能够捕获我需要的一切。

我已经尝试访问Validation事件处理程序的ValidationEventArgs参数中的SourceSchemaObject ,但它始终为null。 我也尝试过XElement的GetSchemaInfo ,看起来也是null。

我正在使用RegEx来识别我想要捕获的特定validation错误,并通过validation事件处理程序的sender参数从XElement中获取数据。 我曾想过将模式转换为XDocument并通过LINQ获取我需要的东西,但在我看来应该有更好的选择

这是我目前的validation方法:

 private List this.validationWarnings; private XDocument xDoc; private XmlSchemaSet schemas = new XmlSchemaSet(); public List Validate() { this.validationWarnings = new List(); // 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); 我的回调方法中的一行只是一个占位符而且还不存在这个方法的目的是做三件事:

  1. 通过在args.Message上使用RegEx来识别特定的validation错误(这已经有效,我已经测试了我计划使用的模式)

  2. 从XDocument中获取与导致错误的特定XElement相关的属性值(例如原始CSV中的行和列号)

  3. 获取架构信息(如果可用),以便可以将字段类型和限制添加到输出消息中。

对于将来读这个问题的人来说,我设法解决了我的问题,尽管方式与我最初提出的方式略有不同。

我遇到的第一个问题是,ValidationEventArgs中的SchemaInfo和XElement的GetSchemaInfo扩展方法都是null。 我以与最初链接的问题相同的方式解决了这个问题….

 List errorElements = new List(); 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 } 

在validation回调之后,似乎没有将Schema信息添加到XObject,因此如果您尝试在validation回调的中间访问它,它将为null,但是如果您捕获该元素,则在之后访问Validate方法已完成,它不会为null。

然而,这开辟了另一个问题。 SchemaInfo对象模型没有很好地记录,我无法解析它以找到我需要的东西。

在我问我原来的问题后,我发现了这个问题。 接受的答案链接到一个非常棒的博客文章,它分解了SchemaInfo对象模型。 我花了一些工作来改进代码以适应我的目的,但是它很好地说明了如何为任何XmlReader元素获取SchemaInfo(我可以将其更改为使用XObject)。