C# 验证XDocument时捕获架构信息

C# 验证XDocument时捕获架构信息,c#,xml,c#-4.0,xsd,linq-to-xml,C#,Xml,C# 4.0,Xsd,Linq To Xml,这与这个问题类似 但是,出于LINQ的目的,我正在使用XDocument 我正在读取/解析一组CSV文件并转换为XML,然后根据XSD模式验证XML 我希望捕获与元素值相关的特定错误,生成一条更加用户友好的消息,并将它们返回给用户,以便可以更正输入数据。我想在输出数据中包括的一项是一些模式信息(例如数字类型的可接受值范围) 在我当前的方法中(我愿意改变),我能够捕获除模式信息之外的所有我需要的东西 我已尝试访问验证事件处理程序的ValidationEventArgs参数中的SourceSchem

这与这个问题类似

但是,出于LINQ的目的,我正在使用XDocument

我正在读取/解析一组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
}
var message=FieldValidationMessage(元素,args)行只是一个占位符,还不存在。此方法的目的是做3件事:

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

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

  • 抓取模式信息(如果可用),以便可以将字段类型和限制添加到输出消息中


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

    我遇到的第一个问题是,ValidationEventArgs中的SchemaInfo和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
    }
    
    List errorElements=new List();
    serializedObject.Validate((发送方,参数)=>
    {
    var exception=(args.exception作为XmlSchemaValidationException);
    if(异常!=null)
    {
    var元素=(exception.SourceObject作为XElement);
    if(元素!=null)
    errorElements.Add(元素);
    }
    });
    foreach(errorElements中的var元素)
    {
    var si=element.GetSchemaInfo();
    //用SchemaInfo做点什么
    }
    

    在验证回调之后,Schema信息不会被添加到XObjor,所以如果您试图在验证回调的中间访问它,它将是NULL,但是如果您捕获该元素,则Access如果在验证方法完成之后,它将不为null。 然而,这又带来了另一个问题。SchemaInfo对象模型没有很好的文档记录,我很难解析它来找到我需要的东西

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

    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
    }