【问题标题】:Capture Schema Information when validating XDocument验证 XDocument 时捕获架构信息
【发布时间】:2011-10-22 10:38:21
【问题描述】:

这类似于这个问题C# Get schema information when validating xml

但是,我正在使用 XDocument 来实现 LINQ。

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

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

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

我尝试访问验证事件处理程序的ValidationEventArgs 参数中的SourceSchemaObject,但始终为空。我还尝试了 XElement 的 GetSchemaInfo ,它似乎也为空。

我正在使用 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. 获取可用的架构信息,以便将字段类型和限制添加到输出消息中。

【问题讨论】:

    标签: c# xml c#-4.0 xsd linq-to-xml


    【解决方案1】:

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

    我遇到的第一个问题是 ValidationEventArgs 和 XElement 的 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,因此如果您尝试在验证回调中间访问它,它将为 null,但如果您捕获元素,那么如果 Validate 方法完成后访问,它不会为空。

    但是,这又引发了另一个问题。 SchemaInfo 对象模型没有很好的文档记录,我在解析它以找到我需要的东西时遇到了麻烦。

    在我提出最初的问题后,我发现了这个question。接受的答案链接到一个非常棒的blog 帖子,该帖子分解了 SchemaInfo 对象模型。我花了一些功夫来完善代码以适应我的目的,但它很好地说明了如何为任何 XmlReader 元素获取 SchemaInfo(我可以将其更改为使用 XObject)。

    【讨论】:

      猜你喜欢
      • 2011-11-20
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 2013-11-20
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多