在验证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件事:

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

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

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

在验证XDocument时捕获模式信息

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

我遇到的第一个问题是,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一起工作)。