在C#中优雅地处理XML文件中的验证错误
描述有点长,请耐心等待.我想处理并验证一个巨大的
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> 我目前能够通过使用带有XMLReader的ValidationEventHandler从XmlSchemaValidationException中恢复,这会抛出我在XML Processing代码中处理的Exception.但是在某些情况下,触发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块将调用close(),并且原始XMLReader位于子树的EndElement上,因此processA中的finally块将导致处理下一个节点A. 但是,遇到XMlException时,调用close方法不会将原始读取器放在子树的EndElement节点上,而是抛出InvalidOperationException. 我尝试使用诸如skip,ReadToXYZ()方法之类的方法,但是当在触发异常的任何节点上调用时,这些方法总是导致InvalidOperationException的XMLExcpetion. 以下是MSDN关于ReadSubTree方法的摘录.
注意:我不能使用.Net 3.5,但欢迎.Net 3.5建议. 解决方法
看到这个问题:
XML Parser Validation Report 您需要区分格式良好的xml(它遵循实际xml所需的规则)和有效的xml(遵循特定xml架构给出的附加规则).从规格:
无论好坏,Visual Studio附带的xml工具都需要非常密切地遵循该规范,因此如果存在格式错误,则不会继续处理.我提供的链接可能会为您提供一些替代方案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |