验证 XDocument 时捕获架构信息
这类似于这个问题 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 件事:
使用 RegEx 识别特定的验证错误在
args.Message
上(这已经有效,我已经测试了我计划使用的模式)从与导致错误的特定 XElement 相关的 XDocument 中获取属性值(例如原始 CSV 中的行号和列号)
获取架构信息(如果可用),以便可以将字段类型和限制添加到输出消息中。
This is similar to this question C# Get schema information when validating xml
However, I am working with an XDocument for LINQ purposes.
I am reading/parsing a set of CSV files and converting to XML, then validating the XML against an XSD schema.
I would like to capture specific errors related to the element values, generate a more user friendly message, and give them back to the user so the input data can be corrected. One of the items I would like to include in the output data is some schema information (such as the range of acceptable values for a numeric type).
In my current approach (which I am open to changing), I am able to capture everything I need except for the schema information.
I've tried accessing the SourceSchemaObject
in the ValidationEventArgs
argument of the Validation event handler, but that is always null. I've also tried the GetSchemaInfo
of the XElement and that appears to be null also.
I am using RegEx to identify the specific validation errors i want to capture, and grabbing data from the XElement via the sender argument of the validation event handler. I've thought of converting the schema to an XDocument and grabbing what I need via LINQ, but it seems to me that there should be a better option
Here's my current Validate Method:
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
}
And here's my callback method:
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);
}
}
The var message = FieldValidationMessage(element, args);
line in my callback method is just a placeholder and does not exist yet The intention of this method is to do 3 things:
Identify specific validation errors by using RegEx on
args.Message
(this already works, I have tested patterns that I plan on using)Grab attribute values from the XDocument related to the specific XElement that is causing the error (such as the row and column number in the original CSV)
Grab the schema information if it is available so field types and restrictions can be added to the output message.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于将来阅读这个问题的任何人,我设法解决了我的问题,尽管方式与我最初提出的方式略有不同。
我遇到的第一个问题是,XElement 的 ValidationEventArgs 和 GetSchemaInfo 扩展方法中的 SchemaInfo 均为 null。我以与我最初链接的问题相同的方式解决了这个问题....
在验证回调之后,架构信息似乎不会添加到 XObject 中,因此如果您尝试在验证过程中访问它回调时,它将为 null,但如果您捕获该元素,然后在 Validate 方法完成后访问 if,则它不会为 null。
然而,这又带来了另一个问题。 SchemaInfo 对象模型没有很好的文档记录,我在解析它以找到我需要的内容时遇到了困难。
我发现这个问题 在我问了我原来的问题之后。接受的答案链接到一个非常好的博客帖子分解 SchemaInfo 对象模型。我花了一些时间来改进代码以适合我的目的,但它很好地说明了如何获取任何 XmlReader 元素的 SchemaInfo(我可以更改该元素以使用 XObject)。
For anyone who reads this question in the future, I managed to solve my problem, albeit in a slightly different way than i originally proposed.
The first problem I was having, that the SchemaInfo both in the ValidationEventArgs and the GetSchemaInfo extension method of XElement were null. I resolved that in the same manner as in the question i linked originally....
It would appear that the Schema info is not added to the XObject until AFTER the validation callback, so if you try to access it in the middle of the validation callback, it will be null, but if you capture the element, then access if after the Validate method has completed, it will not be null.
However, this opened up another problem. The SchemaInfo object model is not well documented and I had trouble parsing it out to find what I needed.
I found this question after I asked my original question. The accepted answer links to a really great blog post that breaks down the SchemaInfo object model. It took me a bit of work to refine the code to suit my purposes, but it does a good job of illustrating how to get the SchemaInfo for any XmlReader element (which I was able to change to work with an XObject).