gpt4 book ai didi

c# - 在 C# 中优雅地处理 XML 文件中的验证错误

转载 作者:数据小太阳 更新时间:2023-10-29 02:21:34 28 4
gpt4 key购买 nike

描述有点长,请多多包涵。我想处理和验证一个巨大的 XML 文件并记录触发验证错误的节点并继续处理下一个节点。 XML 文件的简化版本如下所示。

我想执行的是遇到任何验证错误处理节点“A”或其子节点(XMLException 和 XmlSchemaValidationException)我想停止处理当前节点记录节点“A”的错误和 XML,然后继续到下一个节点“A”。

<Root>
<A id="A1">
<B Name="B1">
<C>
<D Name="ID" >
<E>Test Text 1</E>
</D>
<D Name="text" >
<E>Test Text 1</E>
</D>
</C>
</B>
</A>
<A id="A2">
<B Name="B2">
<C>
<D Name="id" >
<E>Test Text 3</E>
</D>
<D Name="tab1_id" >
<E>Test Text 3</E>
</D>
<D Name="text" >
<E>Test Text 3</E>
</D>
</C>
</B>
</Root>

我目前能够通过将 ValidationEventHandler 与 XMLReader 结合使用来从 XmlSchemaValidationException 中恢复,这会抛出我在 XML 处理代码中处理的异常。但是,在某些情况下,会触发 XMLException,这会导致进程终止。

以下代码片段说明了我正在使用的当前结构;乱七八糟,欢迎提出代码改进建议。

    // Setting up the XMLReader
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IgnoreWhitespace = true;
settings.CloseInput = true;
settings.IgnoreComments = true;
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(null, "schema.xsd");
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
XmlReader reader = XmlReader.Create("Sample.xml", settings);
// Processing XML
while (reader.Read())
if (reader.NodeType == XmlNodeType.Element)
if (reader.Name.Equals("A"))
processA(reader.ReadSubtree());
reader.Close();
// Process Node A
private static void processA(XmlReader A){
try{
// Perform some book-keeping
// Process Node B by calling processB(A.ReadSubTree())
}
catch (InvalidOperationException ex){

}
catch (XmlException xmlEx){

}
catch (ImportException impEx){

}
finally{ if (A != null) A.Close(); }
}
// All the lower level process node functions propagate the exception to caller.
private static void processB(XmlReader B){
try{
// Book-keeping and call processC
}
catch (Exception ex){
throw ex;
}
finally{ if (B != null) B.Close();}
}
// Validation event handler
private static void ValidationCallBack(object sender, ValidationEventArgs e){
String msg = "Validation Error: " + e.Message +" at line " + e.Exception.LineNumber+
" position number "+e.Exception.LinePosition;
throw new ImportException(msg);
}

当遇到 XMLSchemaValidationException 时,finally block 将调用 close() 并且原始 XMLReader 位于子树的 EndElement 上,因此 processA 中的 finally block 将导致处理下一个节点 A。

但是,当遇到 XMlException 时,调用 close 方法不会将原始读取器定位在子树的 EndElement 节点上,并且会抛出 InvalidOperationException。

我尝试使用诸如 skip、ReadToXYZ() 方法之类的方法,但在触发异常的任何节点上调用时,这些方法总是会导致 InvalidOperationException 的 XMLExcpetion。

以下是 MSDN 中有关 ReadSubTree 方法的摘录。

When the new XmlReader has been closed, the original XmlReader will be positioned on the EndElement node of the sub-tree. Thus, if you called the ReadSubtree method on the start tag of the book element, after the sub-tree has been read and the new XmlReader has been closed, the original XmlReader is positioned on the end tag of the book element.

注意:我不能为此使用 .Net 3.5,但是欢迎使用 .Net 3.5 建议。

最佳答案

看到这个问题:
XML Parser Validation Report

您需要区分格式良好 xml(它遵循成为真实 xml 所需的规则)和有效 xml(遵循特定 xml 模式给出的附加规则) ).来自规范:

Once a fatal error is detected, however, the processor must not continue normal processing (i.e., it must not continue to pass character data and information about the document's logical structure to the application in the normal way).

无论好坏,Visual Studio 中包含的 xml 工具都需要非常严格地遵循该规范,因此如果出现格式错误,将不会继续处理。我提供的链接可能会给您一些替代方案。

关于c# - 在 C# 中优雅地处理 XML 文件中的验证错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/699020/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com