如何获取XML模式验证失败位置的XPath(或节点)?

7 .net c# xmldocument linq-to-xml xml-validation

我使用XDocument.Validate(它似乎功能一样XmlDocument.Validate)来验证XML文档针对XSD -这工作得很好,我被告知验证错误.

但是,在ValidationEventHandler(和XmlSchemaException)中,只有一些信息似乎[可靠]公开,例如:

  • 错误消息(即"'X'属性无效 - 值'Y'根据其数据类型'Z'无效 - 模式约束失败"),
  • 严重程度

什么我想是获得了"失败的XPath"为验证失败(如果它是有道理的):那就是,我想获得相对于XML文档失败(而不是XML文本).

有没有办法从中获取"失败的XPath"信息XDocument.Validate?如果没有,可以通过另一种XML验证方法(如XmlValidatingReader1)获取"失败的XPath" 吗?


背景:

XML将作为数据发送到我的Web服务,并通过JSON自动转换(通过JSON.NET)到XML.因此,我开始处理XDocument数据1而不是文本,由于原始JSON数据,它没有保证顺序.REST客户端由于我不打算进入,基本上是XML表单上的HTML表单字段的包装器,服务器上的验证分为两部分 - XML模式验证和业务规则验证.

在业务规则验证中,很容易为不符合一致性的字段返回"XPath",这些字段可用于指示客户端上的失败字段.我想将此扩展到XSD模式验证,它验证基本结构验证,更重要的是,属性的​​基本"数据类型"和"存在".但是,由于所需的自动过程(即突出显示相应的失败字段)和源转换,原始文本消息和源行/列编号本身并不是非常有用.


以下是验证码的片段:

// Start with an XDocument object - created from JSON.NET conversion
XDocument doc = GetDocumentFromWebServiceRequest();

// Load XSD    
var reader = new StringReader(EmbeddedResourceAccess.ReadResource(xsdName));
var xsd = XmlReader.Create(reader, new XmlReaderSettings());
var schemas = new XmlSchemaSet();
schemas.Add("", xsd);

// Validate
doc.Validate(schemas, (sender, args) => {
  // Process validation (not parsing!) error,
  // but how to get the "failing XPath"?
});
Run Code Online (Sandbox Code Playgroud)

更新:我在验证XDocument时找到了Capture Schema Information,它链接到"在文档验证期间访问XML模式信息"(缓存),我从中确定了两件事:

  1. XmlSchemaException可以专门为XmlSchemaValidationException具有SourceObject属性-不过,这总是验证期间返回null:"当一个XmlSchemaValidationException通过验证XmlReader对象验证过程中引发的,SourceObject属性的值为空".

  2. 我可以阅读文档(via XmlReader.Read)并"记住"验证回调之前的路径.虽然这在初始测试中"似乎有效"(没有ValidationCallback),但对我来说感觉相当不合适 - 但我已经找不到其他东西了.

Ser*_*kiy 8

验证事件的发件人是事件的来源.因此,您可以在网络上搜索获取节点XPath的代码(例如,生成XPath表达式)并为事件源生成XPath:

doc.Validate(schemas, (sender, args) => {
  if (sender is XObject)
  { 
     xpath = ((XObject)sender).GetXPath();
  }
});
Run Code Online (Sandbox Code Playgroud)

  • @pst好吧,如果你有缺少的元素,那么我认为它是元素容器的验证错误(你会收到*元素X有不完整的内容*错误).所以,看起来你应该提供父元素的路径,它验证失败,而不是缺少元素(实际上是缺失的,所以在这种情况下路径没有任何意义). (2认同)