代码之家  ›  专栏  ›  技术社区  ›  Jeffrey Hantin

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

  •  2
  • Jeffrey Hantin  · 技术社区  · 15 年前

    我正在使用XML序列化读取大型用户输入文件。如果在读取过程中没有发现输入中的语义错误,我希望能够告诉用户在哪里(文件、行、列)可以找到有问题的元素。XML序列化是否可以实现这一点?

    澄清: 所讨论的代码是用于紧凑框架的IOC容器;许多可能的语义错误与初始化最终对象图时反射失败等相关。这些实际上是运行时错误,而不是读取时或编译时错误。但是,我想告诉他们,不仅因为类blah没有属性fred,所以属性集失败,而且所讨论的属性集位于objects.xml的第1337行。

    • 这些错误不会导致反序列化异常。输入对于反序列化目的有效,不包含语法或数据类型错误。
    • 无法通过启用架构验证来检测错误。输入模式有效。
    • 在读取/反序列化过程中无法检测到错误,因为目标对象的类型可能尚未解决。
    3 回复  |  直到 10 年前
        1
  •  0
  •   John Saunders    15 年前

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

    请注意,XML模式验证错误不是非常用户友好的。您可能希望朝相反的方向工作:使您的用户更难输入无效的文档。使用类似于InfoPath的工具,将表单UI置于XML实例文档之上,这是一种实现这一点的方法。

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


    你要找的东西是不可能做到的。您所指的许多语义错误都将在序列化过程的某个深度显示为异常。第一个异常将终止进程。您只能在呼叫之外捕获这样的异常 XmlSerializer.DeSerialize .在这一点上,任何上下文都消失了,您所拥有的只是异常链。InnerException.InnerException…

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

        2
  •  0
  •   Steve Gilham    15 年前

    有关XML序列化疑难解答的此msdn文章可能有帮助-- http://msdn.microsoft.com/en-us/library/aa302290.aspx 表示:

    就像在案件中 序列化,反序列化() 方法引发无效操作 消息异常

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

    每当出现问题时。这个 异常通常包含 InnerException中的异常 财产。类型 神经感觉根据 发生的实际错误 正在读取XML文档。

    澄清——如果您可以导致对象在反序列化过程中自我验证并失败,那么在您拥有所有上下文的时候,这将是获取问题位置的最佳方法。

        3
  •  -1
  •   Maksim Monakhov    10 年前

    我将为包含错误的对象生成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;
    }
    

    这不是很有效的做法。如果有人知道更好的方法来查找反序列化对象的行号,请写在注释中。