在验证XDocument时捕获模式信息

5
这与这个问题相似 C# Get schema information when validating xml,但是我正在处理一个XDocument以进行LINQ操作。我正在读取/解析一组CSV文件并将其转换为XML,然后根据XSD模式验证XML。我想捕获与元素值相关的特定错误,生成更加用户友好的信息,并将它们返回给用户,以便可以更正输入数据。我想在输出数据中包括一些模式信息(例如数字类型的可接受值范围)。在我的当前方法中(我可以改变),我能够捕获除模式信息之外的所有需要的内容。我尝试访问Validation事件处理程序的ValidationEventArgs参数中的SourceSchemaObject,但它始终为空。我还尝试了XElement的GetSchemaInfo,但那似乎也为空。
我正在使用正则表达式来识别我想要捕获的特定验证错误,并通过验证事件处理程序的 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); 这行代码在我的回调方法中只是一个占位符,目前并不存在。该方法的意图是做三件事情:

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

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

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

1个回答

7

对于未来阅读此问题的任何人,我设法解决了我的问题,尽管方法与我最初提出的略有不同。

我遇到的第一个问题是,在ValidationEventArgs和XElement的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
}

似乎在验证回调之前没有将Schema信息添加到XObject中,因此如果您尝试在验证回调的中间访问它,它将为空,但是如果您捕获元素,则在Validate方法完成后访问它,它将不为空。
然而,这又引出了另一个问题。SchemaInfo对象模型文档不够完善,我很难解析出我需要的内容。
我在提出原始问题后找到了问题,被接受的答案链接到一个非常好的博客文章,详细介绍了SchemaInfo对象模型。我花了一些时间来修改代码以适应我的目的,但它很好地说明了如何获取任何XmlReader元素的SchemaInfo(我已经能够将其更改为与XObject一起使用)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接