title: XDocument.Validate not catching all errors against XSD
body: <p>I have a really strange problem validating an XML document against a valid XSD using C# XDocument.Validate or XMLReaderSettings with required configurations.  The problem is: When there are errors in the XML document, the validation process fails to catch all errors under certain conditions and I can't find a pattern for this anomoly.</p>
  
  <p>Here is my XSD:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
       targetNamespace="http://www.somesite.com/somefolder/messages"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
     &lt;xs:element name="Message"&gt;
      &lt;xs:complexType&gt;
       &lt;xs:sequence&gt;
        &lt;xs:element name="Header"&gt;
           &lt;xs:complexType&gt;
            &lt;xs:sequence&gt;
             &lt;xs:element name="MessageId" type="xs:string" /&gt;
             &lt;xs:element name="MessageSource" type="xs:string" /&gt;
            &lt;/xs:sequence&gt;
         &lt;/xs:complexType&gt;
      &lt;/xs:element&gt;
      &lt;xs:element name="Body"&gt;
         &lt;xs:complexType&gt;
            &lt;xs:sequence&gt;
               &lt;xs:element name="Abc001"&gt;
                  &lt;xs:complexType&gt;
                     &lt;xs:sequence&gt;
                      &lt;xs:element name="Abc002" type="xs:string" /&gt;
                      &lt;xs:element name="Abc003" type="xs:string" minOccurs="0" /&gt;
                      &lt;!--&lt;xs:element name="Abc004" type="xs:string" /&gt;--&gt;
                      &lt;xs:element name="Abc004"&gt;
                         &lt;xs:simpleType&gt;
                           &lt;xs:restriction base="xs:string"&gt;
                             &lt;xs:maxLength value="200"/&gt;
                           &lt;/xs:restriction&gt;
                        &lt;/xs:simpleType&gt;
                      &lt;/xs:element&gt;
                        &lt;xs:element name="Abc005"&gt;
                           &lt;xs:complexType&gt;
                              &lt;xs:sequence&gt;
                                &lt;xs:element name="Abc006" type="xs:unsignedShort" /&gt;
                                &lt;xs:element name="Abc007"&gt;
                                  &lt;xs:complexType&gt;
                                    &lt;xs:sequence&gt;
                                      &lt;xs:element name="Abc008" type="xs:string"/&gt;
                                      &lt;xs:element name="Abc009" type="xs:string" minOccurs="0"/&gt;
                                      &lt;xs:element name="Abc010" type="xs:string"/&gt;
                                    &lt;/xs:sequence&gt;
                                  &lt;/xs:complexType&gt;
                                &lt;/xs:element&gt;
                                &lt;xs:element name="Abc011" type="xs:date" /&gt;
                                &lt;xs:element name="Abc012"&gt;
                                  &lt;xs:complexType&gt;
                                    &lt;xs:sequence&gt;
                                      &lt;xs:element name="Abc013" type="xs:string" /&gt;
                                      &lt;xs:element name="Abc014" type="xs:string" /&gt;
                                    &lt;/xs:sequence&gt;
                                  &lt;/xs:complexType&gt;
                                &lt;/xs:element&gt;
                              &lt;/xs:sequence&gt;
                           &lt;/xs:complexType&gt;
                        &lt;/xs:element&gt;
                     &lt;/xs:sequence&gt;
                  &lt;/xs:complexType&gt;
               &lt;/xs:element&gt;
            &lt;/xs:sequence&gt;
         &lt;/xs:complexType&gt;
      &lt;/xs:element&gt;
     &lt;/xs:sequence&gt;
    &lt;/xs:complexType&gt;
   &lt;/xs:element&gt;
  &lt;/xs:schema&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>And here is the XML document being validated against this XSD:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;Message xmlns="http://www.somesite.com/somefolder/messages"&gt;
   &lt;Header&gt;
    &lt;MessageId&gt;Lorem&lt;/MessageId&gt;
    &lt;MessageSource&gt;Ipsum&lt;/MessageSource&gt;
   &lt;/Header&gt;
   &lt;Body&gt;
    &lt;Abc001&gt;
     &lt;Abc002&gt;dolor&lt;/Abc002&gt;
     &lt;Abc003&gt;sit amet&lt;/Abc003&gt;
     &lt;Abc004&gt;consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.&lt;/Abc004&gt;
     &lt;Abc005&gt;
      &lt;Abc006&gt;1234&lt;/Abc006&gt;
      &lt;Abc007&gt;
       &lt;Abc008&gt;Ut enim&lt;/Abc008&gt;
       &lt;Abc009&gt;ad&lt;/Abc009&gt;
       &lt;Abc010&gt;minim&lt;/Abc010&gt;
      &lt;/Abc007&gt;
      &lt;Abc011&gt;1982-10-17&lt;/Abc011&gt;
      &lt;Abc012&gt;
       &lt;Abc013&gt;veniam&lt;/Abc013&gt;
       &lt;Abc014&gt;nostrud&lt;/Abc014&gt;
      &lt;/Abc012&gt;
     &lt;/Abc005&gt;
    &lt;/Abc001&gt;
   &lt;/Body&gt;
  &lt;/Message&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Now, when I introduce some validation errors into the XML and validate it against the XSD, it does find all the errors as expected.  Here is the error-prone xml (I have marked where the errors are introduced):</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;Message xmlns="http://www.somesite.com/somefolder/messages"&gt;
   &lt;Header&gt;
    &lt;MessageId&gt;Lorem&lt;/MessageId&gt;
    &lt;MessageSource&gt;Ipsum&lt;/MessageSource&gt;
   &lt;/Header&gt;
   &lt;Body&gt;
    &lt;Abc001&gt;
     &lt;Abc002&gt;dolor&lt;/Abc002&gt;
     &lt;Abc003&gt;sit amet&lt;/Abc003&gt;
     
     &lt;!--The value for Abc004 is increased beyond the allowed 200 characters--&gt;
     
     &lt;Abc004&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/Abc004&gt;
     &lt;Abc005&gt;
      &lt;Abc006&gt;1234&lt;/Abc006&gt;
      &lt;Abc007&gt;
       &lt;Abc008&gt;Ut enim&lt;/Abc008&gt;
       &lt;ABC009&gt;AD&lt;/ABC009&gt;
       
       &lt;!--&lt;Abc010&gt;minim&lt;/Abc010&gt;  Required element removed--&gt;
      &lt;/Abc007&gt;
      
      &lt;!--Date formate below is wrong--&gt;
      &lt;Abc011&gt;1982-10-37&lt;/Abc011&gt;
      
      &lt;Abc012&gt;
       &lt;Abc013&gt;veniam&lt;/Abc013&gt;
       &lt;Abc014&gt;nostrud&lt;/Abc014&gt;
      &lt;/Abc012&gt;
     &lt;/Abc005&gt;
  
     &lt;!--the element below is not allowed--&gt;
     &lt;Abc15&gt;Not allowed&lt;/Abc15&gt;
    &lt;/Abc001&gt;
   &lt;/Body&gt;
  &lt;/Message&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>and here is my resulting xml that shows all the errors:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;MessageResponse xmlns="http://www.somesite.com/somefolder/messages"&gt;
      &lt;Result&gt;false&lt;/Result&gt;
      &lt;Status&gt;Failed&lt;/Status&gt;
      &lt;FaultCount&gt;4&lt;/FaultCount&gt;
      &lt;Faults&gt;
          &lt;Fault&gt;
              &lt;FaultCode&gt;ERR01&lt;/FaultCode&gt;
              &lt;FaultMessage&gt;The 'http://www.somesite.com/somefolder/messages:Abc004' element is invalid - The value 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' is invalid according to its datatype 'String' - The actual length is greater than the MaxLength value.&lt;/FaultMessage&gt;
          &lt;/Fault&gt;
          &lt;Fault&gt;
              &lt;FaultCode&gt;ERR02&lt;/FaultCode&gt;
              &lt;FaultMessage&gt;The element 'Abc007' in namespace 'http://www.somesite.com/somefolder/messages' has invalid child element 'ABC009' in namespace 'http://www.somesite.com/somefolder/messages'. List of possible elements expected: 'Abc009, Abc010' in namespace 'http://www.somesite.com/somefolder/messages'.&lt;/FaultMessage&gt;
          &lt;/Fault&gt;
          &lt;Fault&gt;
              &lt;FaultCode&gt;ERR03&lt;/FaultCode&gt;
              &lt;FaultMessage&gt;The 'http://www.somesite.com/somefolder/messages:Abc011' element is invalid - The value '1982-10-37' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:date' - The string '1982-10-37' is not a valid Date value.&lt;/FaultMessage&gt;
          &lt;/Fault&gt;
          &lt;Fault&gt;
              &lt;FaultCode&gt;ERR04&lt;/FaultCode&gt;
              &lt;FaultMessage&gt;The element 'Abc001' in namespace 'http://www.somesite.com/somefolder/messages' has invalid child element 'Abc15' in namespace 'http://www.somesite.com/somefolder/messages'.&lt;/FaultMessage&gt;
          &lt;/Fault&gt;
      &lt;/Faults&gt;
  &lt;/MessageResponse&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Here is the weird part.  When I introduce one more error towards the beginning of the "Abc001" element, and also keep all the other existing errors, the result is totally messed up.  Here is the XML with the newly introduced error:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;Message xmlns="http://www.somesite.com/somefolder/messages"&gt;
   &lt;Header&gt;
    &lt;MessageId&gt;Lorem&lt;/MessageId&gt;
    &lt;MessageSource&gt;Ipsum&lt;/MessageSource&gt;
   &lt;/Header&gt;
   &lt;Body&gt;
    &lt;Abc001&gt;
     &lt;!--newly introduced error - removed the following element--&gt;
     &lt;!--&lt;Abc002&gt;dolor&lt;/Abc002&gt;--&gt;
     &lt;Abc003&gt;sit amet&lt;/Abc003&gt;
     &lt;!--The value for Abc004 is increased beyond the allowed 200 characters--&gt;
     &lt;Abc004&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/Abc004&gt;
     &lt;Abc005&gt;
      &lt;Abc006&gt;1234&lt;/Abc006&gt;
      &lt;Abc007&gt;
       &lt;Abc008&gt;Ut enim&lt;/Abc008&gt;
       &lt;ABC009&gt;AD&lt;/ABC009&gt;
       &lt;!--&lt;Abc010&gt;minim&lt;/Abc010&gt;--&gt;
      &lt;/Abc007&gt;
      &lt;Abc011&gt;1982-10-37&lt;/Abc011&gt;
      &lt;Abc012&gt;
       &lt;Abc013&gt;veniam&lt;/Abc013&gt;
       &lt;Abc014&gt;nostrud&lt;/Abc014&gt;
      &lt;/Abc012&gt;
     &lt;/Abc005&gt;
     &lt;!--the element below is not allowed--&gt;
     &lt;Abc15&gt;Not allowed&lt;/Abc15&gt;
    &lt;/Abc001&gt;
   &lt;/Body&gt;
  &lt;/Message&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>and finally, here is the validation result:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;MessageResponse xmlns="http://www.somesite.com/somefolder/messages"&gt;
      &lt;Result&gt;false&lt;/Result&gt;
      &lt;Status&gt;Failed&lt;/Status&gt;
      &lt;FaultCount&gt;1&lt;/FaultCount&gt;
      &lt;Faults&gt;
          &lt;Fault&gt;
              &lt;FaultCode&gt;ERR01&lt;/FaultCode&gt;
              &lt;FaultMessage&gt;The element 'Abc001' in namespace 'http://www.somesite.com/somefolder/messages' has invalid child element 'Abc003' in namespace 'http://www.somesite.com/somefolder/messages'. List of possible elements expected: 'Abc002' in namespace 'http://www.somesite.com/somefolder/messages'.&lt;/FaultMessage&gt;
          &lt;/Fault&gt;
      &lt;/Faults&gt;
  &lt;/MessageResponse&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Here is my C# code I am using to validate:</p>
  
  <pre><code>public async Task&lt;IMIDPreValidationAckMessage&gt; ValidateXmlMessage( XDocument doc )
      {
          var result = new PreValidationAckMessage();
          result.Result = true;
          result.Status = "Succeeded";
  
          var xsd = HttpContext.Current.Server.MapPath( "~/message01.xsd" );
  
          try
          {
              var uri = new System.Uri(xsd);
  
              var localPath = uri.LocalPath;
  
              var docNameSpace = doc.Root.Name.Namespace.NamespaceName;
  
              XmlSchemaSet schemas = new XmlSchemaSet();
              schemas.Add( docNameSpace, localPath );
  
              XmlReaderSettings xrs = new XmlReaderSettings();
              xrs.ValidationType = ValidationType.Schema;
              xrs.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
              xrs.Schemas = schemas;
  
              result.XSDNamespace = doc.Root.GetDefaultNamespace().NamespaceName;
              var errCode = 1;
  
              xrs.ValidationEventHandler += ( s, e ) =&gt;
              {
                  var msg = e.Message;
                  result.Result = false;
                  result.Status = "Failed";
                  result.FaultCount++;
                  result.Faults.Add( new Fault
                  {
                      FaultCode = "ERR" + errCode++.ToString().PadLeft( 2, '0' ),
                      FaultMessage = e.Message
                  } );
              };
  
              using ( XmlReader xr = XmlReader.Create( doc.CreateReader(), xrs ) )
              {
                  while ( xr.Read() ) { }
              }
          }
          catch ( System.Exception ex )
          {
              result.Result = false;
              result.Status = "Unknown Error";
          }
          return result;
      }
  </code></pre>
  
  <p>Can someone please tell me what is wrong here?</p>