XmlSerializer:如何捕获每个反序列化元素的文件/行/列信息?

时间:2009-07-25 23:58:36

标签: .net xml-serialization

我正在使用XML序列化来读取大型用户输入文件。如果在读取期间未发现输入中存在语义错误,我希望能够告诉用户他们可以在哪里(文件,行,列)找到有问题的元素。这可以通过XML序列化来实现吗?

澄清:有问题的代码是Compact Framework的IoC容器;在初始化最终对象图时,许多可能的语义错误与诸如反射失败之类的事物有关。这些是有效的运行时错误,而不是读取时间或编译时错误。但是,我想告诉他们不仅属性集失败,因为类Blah没有属性Fred,而且有问题的属性设置在Objects.xml的第1337行。

  • 错误不会导致反序列化异常。输入对于反序列化目的有效,并且不包含语法或数据类型错误。
  • 启用架构验证无法检测到错误。输入显示有效。
  • 在读取/反序列化过程中无法检测到错误,因为目标对象的类型可能尚未解析。

3 个答案:

答案 0 :(得分:0)

这篇关于XML序列化疑难解答的MSDN文章可能有所帮助 - http://msdn.microsoft.com/en-us/library/aa302290.aspx它表明:

  

就像在案件中一样   序列化,反序列化()   方法抛出InvalidOperation   消息的异常

There is an error in XML document
(<line>, <column>).
  

每当出现问题时。这个   异常通常包含真实的   InnerException中的异常   属性。的类型   InnerException根据不同而不同   发生的实际错误   阅读XML文档。

澄清 - 如果您可以在反序列化期间使对象自行验证并失败,那么这将是获得所有上下文时获取问题位置的最佳方法。

答案 1 :(得分:0)

如果您有描述文档的模式,那么在反序列化时可以使用XmlReader进行验证。处理验证错误,您将能够为用户提供比他们想要的更多详细信息。

请注意,XML Schema验证错误不是非常用户友好。您可能希望以相反的方向工作:使用户更难以输入无效文档。使用像InfoPath这样的工具将表单UI放在XML实例文档上是一种方法。

另一种方法是在Visual Studio Express 2008中使用XML编辑器。如果您为它提供模式,它不仅会验证XML,还会提供IntelliSense - 它将显示有效的下一个元素或属性,甚至会显示包含架构文档的工具提示。


没有办法做你想要的。您所指的许多语义故障将在序列化过程的某个深处显示为异常。第一个例外将终止该过程。您只能在致电XmlSerializer.DeSerialize之外捕获此类异常。那时,任何上下文都消失了,你所拥有的就是Exception.InnerException.InnerException ......

如果通过实现IXmlSerializable进行自己的反序列化,那么您将能够在类中保留异常处理,并且可以访问正在使用的XmlReader。如果该阅读器维护行和列信息,那么您应该能够将该信息添加到异常中。

答案 2 :(得分:-1)

我为包含错误的对象生成XPath,然后使用XDocument查找相应的XML元素。

public static int GetLineNumber(XDocument document, string xPath) 
{
        var xmlNamespaceManager = new XmlNamespaceManager(new NameTable());
        xmlNamespaceManager.AddNamespace("myns", "http://myns.com");
        var xPathEvaluate = document.XPathSelectElement(xPath, xmlNamespaceManager);
        return ((IXmlLineInfo)xPathEvaluate).LineNumber;
}

这不是一种非常有效的练习。如果有人知道更好的方法来查找反序列化对象的行号,请写下评论。