title: Single-pass Read and Validate XML vs referenced XSD in C#
body: <p>I'm trying to read the data from an XML file, validating it against the XSD it suggests, into a single data structure (such as XmlDocument). I have a solution, but it requires 2 passes through the file, and I'm wondering if there's a single-pass solution.</p>
  
  <p><strong>MyBooks.xml:</strong></p>
  
  <pre><code>&lt;Books xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
       xsi:noNamespaceSchemaLocation='books.xsd' id='999'&gt;
      &lt;Book&gt;Book A&lt;/Book&gt;
      &lt;Book&gt;Book B&lt;/Book&gt;
  &lt;/Books&gt;
  </code></pre>
  
  <p><strong>Books.xsd:</strong></p>
  
  <pre><code>&lt;xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
      elementFormDefault='qualified'
      attributeFormDefault='unqualified'&gt;
      &lt;xs:element name='Books'&gt;
          &lt;xs:complexType&gt;
              &lt;xs:sequence&gt;
                  &lt;xs:element name='Book' type='xs:string' /&gt;
              &lt;/xs:sequence&gt;
              &lt;xs:attribute name='id' type='xs:unsignedShort' use='required' /&gt;
          &lt;/xs:complexType&gt;
      &lt;/xs:element&gt;
  &lt;/xs:schema&gt;
  </code></pre>
  
  <p>Let's say MyBooks.xml and Books.xsd are in the same directory.</p>
  
  <p><strong>Validate:</strong></p>
  
  <pre><code>//Given a filename pointing to the XML file
  var settings = new XmlReaderSettings();
  
  settings.ValidationType = ValidationType.Schema;
  
  settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
  settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
  settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
  
  settings.CloseInput = true;
  settings.ValidationEventHandler += new ValidationEventHandler(ValidationCB);
  //eg:
  //private static void ValidationCB(object sender, ValidationEventArgs args)
  //{ throw new ApplicationException(args.Message); }
  
  using(var reader = XmlReader.Create(filename, settings))
  { while(reader.Read()) ; }
  </code></pre>
  
  <p><strong>Read into XmlDocument:</strong></p>
  
  <pre><code>XmlDocument x = new XmlDocument();
  x.Load(filename);
  </code></pre>
  
  <p>Sure, I could collect the nodes as the read from the XmlReader is taking place, but I'd rather not have to do it myself, if possible. Any suggestion?</p>
  
  <p>Thanks in advance</p>