我正在使用XML序列化来读取大型用户输入文件。如果在读取期间未发现输入中存在语义错误,我希望能够告诉用户他们可以在哪里(文件,行,列)找到有问题的元素。这可以通过XML序列化来实现吗?
澄清:有问题的代码是Compact Framework的IoC容器;在初始化最终对象图时,许多可能的语义错误与诸如反射失败之类的事物有关。这些是有效的运行时错误,而不是读取时间或编译时错误。但是,我想告诉他们不仅属性集失败,因为类Blah没有属性Fred,而且有问题的属性设置在Objects.xml的第1337行。
答案 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;
}
这不是一种非常有效的练习。如果有人知道更好的方法来查找反序列化对象的行号,请写下评论。