使用XML阅读器进行XSD验证,收集验证错误。 (C#)

时间:2012-10-24 14:01:56

标签: xsd xmlreader

我目前正在努力使用XMLSerializer来执行XSD验证并收集文件中的验证错误。任务是根据包含值集信息,状态信息等的自定义XSD来验证文件。

我的问题如下:当使用XMLReader时,如果我们将一个监听器附加到读者的ValidationEvents(通过XMLReaderSettings),它会在第一个错误处停止。所以我只是捕获我记录错误的异常。到目前为止一切都很好,问题在记录异常后开始出现。在此之后,XMLReader转到失败字段的结束标记,但由于无法解释的异常,我无法验证下一个字段。

要实践,这是我的代码,我抓住了异常:

  private bool TryDeserialize(XmlSerializer ser, XmlReader read,out object item)
  {
     string Itemname = read.Name;
     XmlReader read2 = read.ReadSubtree();
     try
     {
         item= ser.Deserialize(read2);
        return true;
     }
     catch (Exception e)
     {
        _ErrorList.Add("XSD error at " + Itemname + ": " + e.InnerException.Message);
        item = null;
        return false;
     }

  }

这个例程运作良好,但接下来的问题是有问题的。假设我将以下XML代码段传递给此代码:

      <a>2885</a>
  <b>ABC</b>
  <c>5</c>

假设'b'可能没有'ABC'作为值,因此我收到XSD错误。在这结束时,xmlreader将在 'EndElement,Name = b' 除非我得到例外,否则我根本无法移动。如果我执行xmlreader.read,那么我得到以下异常(在此处删除命名空间):

"e = {"The element 'urn:iso:.....b' cannot contain child element 'urn:iso:.....:c' because the parent element's content model is text only."}"

在此之后,xmlreader位于'Element,Name = c',所以看起来不错,但是当尝试使用上面的代码反序列化它时,我得到以下异常:

'_message = "The transition from the 'ValidateElement' method to the 'ValidateText' method is not allowed."'

我真的不知道如何重复它。我尝试没有第二个读者阅读子树,但我有同样的问题。请给我一些建议,我真的卡住了。非常感谢提前!

迎接

1 个答案:

答案 0 :(得分:0)

您可能需要考虑以下事项:

  • 通常,并不总是能够“收集”所有错误,因为验证解析器可以在发生某些类型的错误时自由放弃验证过程,特别是那些将验证器置于其中的状态它无法可靠地恢复。例如,验证者在遇到简单类型的约束方面违规后仍可能继续,但如果它在意外内容中运行,它将跳过整个部分。

  • 与解析到DOM不同,DOM的加载不受验证读取器验证的影响,反序列化到对象中(或者至少应该)是完全不同的: DOM即将形成良好;反序列化,即强类型是有效

直觉上我认为如果你得到验证错误,继续反序列化和进一步验证有什么意义?

尝试独立于反序列化验证XML。如果确实你用这种方法标记了更多错误,那么上面应该解释原因。如果没有,那么你正在追逐其他东西。