具有正确错误处理(行号、原始文本等)的XML读取

本文关键字:文本 原始 读取 XML 行号 错误 处理 | 更新日期: 2023-09-27 18:24:04

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

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

  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属性,它是一个字符串。但这仍然不是我想要展示的全部信息。

具有正确错误处理(行号、原始文本等)的XML读取

不会从StringReader读取行号信息。如果在FileStream上使用StreamReader,则可以获得行号。

您正在查找的这些附加元数据被称为"架构后验证信息集"。

在ValidationEventHandler中查看参数。异常属性。它是XmlSchemaException类型,包含行号等。

你可以保留所有的错误,然后再进行解析。

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

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

一旦得到提示,就可以将其与原始文档中的每一行进行比较。

几年前我做过类似的事情(除了行号),效果非常好。即使对于大型xml文档也是如此。