这与此问题类似C# Get schema information when validating xml
但是,我正在使用XDocument进行LINQ目的。
我正在阅读/解析一组CSV文件并转换为XML,然后根据XSD架构验证XML。
我想捕获与元素值相关的特定错误,生成更加用户友好的消息,并将它们返回给用户,以便可以更正输入数据。我想在输出数据中包含的一个项目是一些架构信息(例如数字类型的可接受值的范围)。
在我目前的方法中(我愿意改变),除了架构信息之外,我能够捕获所需的一切。
我尝试访问Validation事件处理程序的SourceSchemaObject
参数中的ValidationEventArgs
,但它始终为null。我也尝试了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);
行只是一个占位符而且还不存在这个方法的目的是做三件事:
使用args.Message
上的RegEx识别特定的验证错误(这已经有效,我已经测试了我计划使用的模式)
从XDocument中获取与导致错误的特定XElement相关的属性值(例如原始CSV中的行号和列号)
获取架构信息(如果可用),以便可以将字段类型和限制添加到输出消息中。
答案 0 :(得分:6)
对于将来阅读此问题的任何人,我设法解决了我的问题,尽管方式与我最初提出的方式略有不同。
我遇到的第一个问题是,ValidationEventArgs中的SchemaInfo和XElement的GetSchemaInfo扩展方法都是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,因此如果您尝试在验证回调的中间访问它,它将为null,但是如果您捕获该元素,那么访问如果在Validate方法完成后,它将不为null。
然而,这又开启了另一个问题。 SchemaInfo对象模型没有很好地记录,我无法解析它以找到我需要的东西。
在我提出原始问题后,我发现了question。接受的答案链接到一个非常好的blog帖子,该帖子分解了SchemaInfo对象模型。我花了一些工作来改进代码以适应我的目的,但是它很好地说明了如何为任何XmlReader元素获取SchemaInfo(我能够将其更改为使用XObject)。