【问题标题】:XML reading with proper error handling (line numbers, original text etc)正确处理错误的 XML 读取(行号、原始文本等)
【发布时间】:2012-03-01 16:47:04
【问题描述】:

我想读取一个相当大的 xml 文件。它足够小以适合内存,但仍然非常大。在读取 XML 时,它会根据 XSD 进行验证。但是,这并不能防止在系统中使用读取的数据进行进一步操作时发生业务错误。当发生此类业务错误时(在 XSD 验证之后),我希望能够描述 行号列号 用于我的 xml 中元素的开始和结束位置。此外,在这种情况下,显示从文件中读取的 输入 xml 将是用户友好的。

使用 xsd.exe 我已经生成了所有数据类的代码,并使用

  using (var reader = new StringReader(content))
  {
    var errors = new List<string>();
    var settings = new XmlReaderSettings();
    settings.Schemas.Add("urn:import-schema", "Import.xsd");
    settings.ValidationEventHandler += (o, args) => errors.Add(args.Message);
    settings.ValidationType = ValidationType.Schema;

    using (XmlReader xr = XmlReader.Create(reader, settings))
    {
      var xs = new XmlSerializer(typeof(ImportRoot));
      var result = (ImportRoot) xs.Deserialize(xr);
      if (errors.Any())
        throw new Exception(string.Join("\n\n", errors));
      return result;
    }
  }
}

但是,我似乎无法找到我正在寻找的元信息。我也检查了XDocument 类。这里的元素似乎有一个Value 属性,它是一个字符串。但这还不是我想要展示的全部信息。

【问题讨论】:

    标签: c# xml xml-serialization xml-parsing


    【解决方案1】:

    行号信息不是从StringReader 中读取的。如果您在FileStream 上使用StreamReader,您将能够获得行号。

    您要查找的此附加元数据称为"Post Schema Validation Infoset"

    【讨论】:

    • 不是。该信息将在验证异常对象中可用。
    • 我不明白你的意思。在 FileStream 上使用 StreamReader 时,我已经能够获取此信息。
    • 并且该信息仅在模式验证后才会被填充。您正在寻找“后架构验证信息集”。
    【解决方案2】:

    在您的 ValidationEventHandler 中查看 args.Exception 属性。它是一个XmlSchemaException 类型,包含行号等。

    您可以保留所有错误,然后再对其进行解析。

    var errors = new List<ValidationEventArgs>();
    ....
    settings.ValidationEventHandler += (o, args) => errors.Add(args);
    

    可以通过将它们实现为自定义 xslt 函数来处理业务验证错误。请参阅此article。一旦你有一个实现了IXsltContextFunction 的函数,你就可以检查Invoke 方法中的XPathNavigator 以获得关于你在文档中的位置的提示

    获得提示后,您可以将其与原始文档中的每一行进行比较。

    几年前我做过类似的事情(除了行号),效果很好。即使是大型 xml 文档。

    【讨论】:

    • 但它不是模式验证问题!它在读取 xml 后的业务验证并针对 XSD 进行了很好的验证。
    • 好的,明白了。可以指定一个业务验证规则作为例子吗?
    • 当然。假设您进行产品导入,并且 SKU(产品 ID)必须是唯一的。那么您可以拥有一个有效的 xml,但其中一个包含您要导入的系统中已经存在的产品。
    猜你喜欢
    • 2013-06-12
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 2010-12-03
    • 2012-05-15
    相关资源
    最近更新 更多