title: Should .Net XML Schema Validation stop upon reaching first invalid element?
body: <p>I have an XML string and a Schema loaded up and passed into a function. I have it validating the XML against the schema correctly, however it always stops validating at the scope of the first invalid element. Invalid data, it keeps going, invalid/missing attributes, keeps going, but invalid elements, it stops and will not validate further within that scope.</p>
  
  <p>The schema is as follows:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-16"?&gt;
  &lt;xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
    &lt;xs:element name="root"&gt;
      &lt;xs:complexType&gt;
        &lt;xs:sequence&gt;
          &lt;xs:element name="items"&gt;
            &lt;xs:complexType&gt;
              &lt;xs:sequence maxOccurs="unbounded"&gt;
                &lt;xs:element name="foo"&gt;
                  &lt;xs:complexType&gt;
                    &lt;xs:sequence&gt;
                      &lt;xs:element name="bar" type="xs:integer" /&gt;
                      &lt;xs:element name="bat" type="xs:integer" /&gt;
                    &lt;/xs:sequence&gt;
                    &lt;xs:attribute name="attr1" type="xs:integer" use="required" /&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>
  
  <p>Xml is as follows:</p>
  
  <pre><code>&lt;root&gt;
    &lt;items&gt;
      &lt;foo attr1='1'&gt;
        &lt;invalid0&gt;1&lt;/invalid0&gt;
        &lt;invalid1&gt;b&lt;/invalid1&gt;
      &lt;/foo&gt;
      &lt;foo attr1='1'&gt;
        &lt;invalid2&gt;b&lt;/invalid2&gt;
        &lt;bat&gt;b&lt;/bat&gt;
      &lt;/foo&gt;
      &lt;foo attr1='1'&gt;
        &lt;bar&gt;3&lt;/bar&gt;
      &lt;/foo&gt;
      &lt;invalidFoo attr1='1'&gt;
        &lt;bar&gt;d&lt;/bar&gt;
        &lt;bat&gt;2&lt;/bat&gt;
      &lt;/invalidFoo&gt;
      &lt;foo&gt;
        &lt;bar&gt;3&lt;/bar&gt;
        &lt;bat&gt;q&lt;/bat&gt;
      &lt;/foo&gt;
    &lt;/items&gt;
  &lt;/root&gt;
  </code></pre>
  
  <p>So, what happens in this example the validator reaches the first <code>&lt;foo&gt;</code> and sees <code>&lt;invalid0&gt;</code> and doesn't validate within the <code>&lt;foo&gt;</code> any further and therefore misses the <code>&lt;invalid1&gt;</code>. Validator moves on to the next <code>&lt;foo&gt;</code>.</p>
  
  <p>The next <code>&lt;foo&gt;</code> it sees there is an <code>&lt;invalid2&gt;</code> which doesn't belong there and doesn't bother to catch the invalid data for the <code>&lt;bat&gt;</code> element (string instead of integer). It goes directly to the next <code>&lt;foo&gt;</code></p>
  
  <p>It makes it to the next <code>&lt;foo&gt;</code> element and throws an error about a missing <code>&lt;bat&gt;</code> and moves on to the next <code>&lt;foo&gt;</code>, cool.</p>
  
  <p>Now it gets to the the <code>&lt;invalidFoo&gt;</code> and rightfully so, does't do any validation inside of the <code>&lt;invalidFoo&gt;</code> because, of course, what's an <code>&lt;invalidFoo&gt;</code>?</p>
  
  <p><strong>The sticking point for me is, at this point the validator stops validating all the following <code>&lt;foo&gt;</code> sibling elements</strong>, so the invalid data in the last <code>&lt;bat&gt;</code> is not caught. So now, the reason I'm asking is because the way I'm using validation is to try to catch all errors (or at least as many as possible) and pass them back to the user. The first test I did in my actual code was the equivalent of this:</p>
  
  <pre><code>&lt;root&gt;
    &lt;items&gt;
      &lt;invalidFoo attr1='1'&gt;
        &lt;invalid0&gt;1&lt;/invalid0&gt;
        &lt;invalid1&gt;b&lt;/invalid1&gt;
      &lt;/invalidFoo&gt;
      &lt;foo attr1='1'&gt;
        &lt;invalid2&gt;b&lt;/invalid2&gt;
        &lt;bat&gt;b&lt;/bat&gt;
      &lt;/foo&gt;
      &lt;foo attr1='1'&gt;
        &lt;bar&gt;3&lt;/bar&gt;
      &lt;/foo&gt;
      &lt;invalidFoo attr1='1'&gt;
        &lt;bar&gt;d&lt;/bar&gt;
        &lt;bat&gt;2&lt;/bat&gt;
      &lt;/invalidFoo&gt;
      &lt;foo&gt;
        &lt;bar&gt;3&lt;/bar&gt;
        &lt;bat&gt;q&lt;/bat&gt;
      &lt;/foo&gt;
    &lt;/items&gt;
  &lt;/root&gt;
  </code></pre>
  
  <p>So, the validator saw that first <code>&lt;invalidFoo&gt;</code> and stopped dead. For the longest time, I was assuming that for some reason the validation was always stopping on the first error. It wasn't until I added a valid <code>&lt;foo&gt;</code> back that it started catching and accumulating the other invalid data errors in succession. But as soon as it hits an invalid element tagname, all sibling/child-level validation is skipped. It only happens upon invalid elements, not attributes or data.</p>
  
  <p>Now, I'm not saying this is right or wrong...I'm asking if this is right or wrong? <strong>Should the validator keep going, especially in the case of sibling elements? Or should it be stopping and basically calling an entire list of elements invalid based on a previous one being invalid? What is the expected behaviour of the Xml Schema Validator in this situation?</strong></p>
  
  <p>This is all being done using the following C# code (which works as I expect it to):</p>
  
  <pre><code> public static void ValidateAgainstSchema(string XMLSourceDocument, XmlSchemaSet validatingSchemas)
   {
      if (validatingSchemas == null)
      {
          throw new ArgumentNullException("In ValidateAgainstSchema: No schema loaded.");
      }
  
      string errorHolder = string.Empty;
      ValidationHandler handler = new ValidationHandler();
  
      XmlReaderSettings settings = new XmlReaderSettings();
      settings.CloseInput = true;
      settings.ValidationType = ValidationType.Schema;
      settings.ValidationEventHandler += new ValidationEventHandler(handler.HandleValidationError);
      settings.Schemas.Add(validatingSchemas);
      settings.ValidationFlags =
          XmlSchemaValidationFlags.ReportValidationWarnings |
          XmlSchemaValidationFlags.ProcessIdentityConstraints |
          XmlSchemaValidationFlags.ProcessInlineSchema |
          XmlSchemaValidationFlags.ProcessSchemaLocation;
  
      StringReader srStringReader = new StringReader(XMLSourceDocument);
  
      using (XmlReader validatingReader = XmlReader.Create(srStringReader, settings))
      {
          while (validatingReader.Read()) { }
      }
  
      if (handler.MyValidationErrors.Count &gt; 0)
      {
          foreach (String messageItem in handler.MyValidationErrors)
          {
              errorHolder += messageItem;
          }
          throw new XmlSchemaValidationException(errorHolder);
      }
  }
  </code></pre>
  
  <p>The validation event handler just catches the errors and adds them to an <code>IList&lt;string&gt;</code> for displaying later all together.</p>