Gracefully handle validation errors in an XML file in C #

Description bit on the longer side, please carry me. I would like to process and validate a huge XML file and register the node that caused the validation error and continue processing the next node. The following is a simplified version of the XML file.

What I would like to accomplish is to encounter any node "A" validation error handling or its children (both XMLException and XmlSchemaValidationException). I would like to stop processing the current node of the error log and XML for node "A" and go to the next node "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>

XmlSchemaValidationException ValidationEventHandler XMLReader, , 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 close(), XMLReader EndElement , , , finally A node A.

, XMlException, close EndElement node InvalidOperationException.

, skip, ReadToXYZ(), XMLExcpetion InvalidOperationException node, .

MSDN ReadSubTree.

XmlReader , XmlReader EndElement node. , ReadSubtree , XmlReader , XmlReader .

. .Net 3.5 . 3.5. .

+3
2

:
XML

xml ( , xml) xml ( , xml). :

( ).

, xml, Visual Studio, , , , . , , .

+5

, , XmlReader.Close():

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 += ValidationCallBack;
using (XmlReader reader = XmlReader.Create("Sample.xml", settings))
{
    while (reader.Read())
    {
        if (reader.NodeType == XmlNodeType.Element &&
            reader.Name.Equals("A"))
        {
            using (
                XmlReader subtree = reader.ReadSubtree())
            {
                try {
                    processA(subtree);
                }
                catch (ImportException ex) { // log it at least }
                catch (XmlException ex) {// log this too }
                // I would not catch InvalidOperationException - too general
            }
        }
    }
}

private static void processA(XmlReader A)
{
    using (XmlReader subtree = A.ReadSubtree())
    {
        processB(subtree);
    }
}

// All the lower level process node functions propagate the exception to caller.  
private static void processB(XmlReader B)
{
}

, , processA. , - processA . - , .

+2

Source: https://habr.com/ru/post/1705601/


All Articles