我想读一个相当大的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
属性是一个字符串。但这仍然不是我想要显示的所有信息。
答案 0 :(得分:2)
不会从StringReader
读取行号信息。如果您在StreamReader
上使用FileStream
,则可以获取该行号。
您要查找的其他元数据称为"Post Schema Validation Infoset"。
答案 1 :(得分:0)
在ValidationEventHandler中查看args.Exception属性。它是XmlSchemaException类型,包含行号等。
您可以保留所有错误,然后再解析它们。
var errors = new List<ValidationEventArgs>();
....
settings.ValidationEventHandler += (o, args) => errors.Add(args);
可以通过将它们实现为自定义xslt函数来处理业务验证错误。见article。一旦有了实现IXsltContextFunction的函数,就可以在Invoke方法中检查XPathNavigator,了解提示,了解文档中的位置。
获得提示后,您可以将其与原始文档中的每一行进行比较。
几年前我做了类似的事情(除了行号),它的效果非常好。即使对于大型xml文档也是如此。