大型xml验证和分组失败消息
本文关键字:失败 消息 xml 验证 大型 | 更新日期: 2023-09-27 17:50:34
我正在尝试使用xsd-schema验证大型xml文件。下面是我的代码:
void Validate()
{
var settings = new XmlReaderSettings();
settings.Schemas.Add(null, selectedXsd);
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += ValidationCallBack;
var reader = XmlReader.Create(selectedXml, settings);
while (reader.Read()) {}
}
public void ValidationCallBack(object sender, ValidationEventArgs args)
{
Console.WriteLine(args.Message);
}
下面是我的示例xml文件:
<root>
<a>
<b>1</b>
<c>two</c>
</a>
<a>
<b>1</b>
</a>
<a>
<b>1</b>
<c>2</c>
<d>3</d>
</a>
</root>
存在已定义的强模式规则。元素a
只能包含子元素b
和c
,它们都是必需的,并且都是整数。我的程序给我写了以下错误:
The 'c' element is invalid - The value 'two' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:int' - The string 'two' is not a valid Integer value.
The element 'a' has incomplete content. List of possible elements expected: 'b, c'.
The element 'a' has invalid child element 'd'. List of possible elements expected: 'b, c'
看起来很好,但问题是文件大小大(> 2gb),可能有数千个错误。当特定元素的值无效时,它应该"分组"这些错误,不管它们的值是多少。当元素丢失时,它应该对错误进行适当的分组,甚至可能计算它们丢失的次数。当不同的节点中缺少不同的元素时,它应该报告另一个错误。以此类推所有可能的错误。但它只有信息是字符串args.Message
和sender
,这实际上是XmlReader元素。
我的问题:有没有最好的方法来做验证在我的方式,不解析参数。消息字符串和排除内存不足的异常考虑巨大的文件大小?也许我应该用另一个图书馆?
如果你能接受一个有一点反思的解决方案,并希望按一般错误(无效的元素,不正确的类型等)分组,你可以这样做:
在类
中声明两个变量Dictionary<string, List<XmlSchemaException>> exps = new Dictionary<string, List<XmlSchemaException>>();
PropertyInfo ErrorGetResProp;
在验证方法中找到非公共属性:
ErrorGetResProp = typeof(XmlSchemaValidationException).GetProperty("GetRes", BindingFlags.NonPublic | BindingFlags.Instance);
然后在验证回调中你可以收集错误:
string error = ErrorGetResProp.GetValue(args.Exception) as string;
List<XmlSchemaException> e = null;
if (!exps.TryGetValue(error, out e))
exps[error] = e = new List<XmlSchemaException>();
e.Add(args.Exception);
之后,你有一个字典exps
,其中包含Keys
中所有不同的错误类型(没有很快找到关于可能值的文档,但它可以很容易地手动收集)。字典中的值将提供错误,因此您可以轻松地Count()
它们,或显示Message
,以及LineNumber
s等。
还有另一个非公共属性Args
,它将告诉元素名称和其他信息,因此如果需要,您也可以获取这些信息。如果你想按"element X missing"分组,信息就在那里。
您也可以自然地按消息分组,但它可能无法提供足够的分组。
当然,如果在验证时内存耗尽,这将没有帮助,但至少它将提供一种更好的处理错误类型的方法。