title: compile schemas with included xsd files
body: <p>I have static method, which i use to validate a XML File against a XSD File. This works fine, until there is an XSD File which includes another XSD File.</p>
  
  <p>Example, where i got troubles:</p>
  
  <p><strong>TYPES.XSD:</strong></p>
  
  <pre><code>&lt;xs:simpleType name="MY_AMOUNT"&gt;
      &lt;xs:restriction base="xs:decimal"&gt;
          &lt;xs:maxInclusive value="999999999999.99"/&gt;
          &lt;xs:minInclusive value="-999999999999.99"/&gt;
          &lt;xs:totalDigits value="14"/&gt;
          &lt;xs:fractionDigits value="2"/&gt;
      &lt;/xs:restriction&gt;
  &lt;/xs:simpleType&gt;
  </code></pre>
  
  <p><strong>MAIN.XSD:</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"&gt;
      &lt;xs:include schemaLocation="TYPES.xsd"/&gt;
      &lt;xs:element name="ROOT"&gt;
          &lt;xs:complexType&gt;
              &lt;xs:sequence&gt;
                  &lt;xs:element ref="SOMEREF1"/&gt;
                  &lt;xs:element ref="SOMEREF2"/&gt;
                  &lt;xs:element name="AMOUNT" type="MY_AMOUNT" minOccurs="0"/&gt;
              &lt;/xs:sequence&gt;
          &lt;/xs:complexType&gt;
      &lt;/xs:element&gt;
  &lt;/xs:schema&gt;
  </code></pre>
  
  <p><strong>VALIDATION CODE:</strong></p>
  
  <pre><code>public static class XmlUtils
  {
      private static string Errors = string.Empty;
  
      public static bool ValidateAgainstXSD(string xmlFilePath, string xsdFilePath, ref string message)
      {
          try
          {
              var settings = new XmlReaderSettings();
  
              settings.ValidationType = ValidationType.Schema;
              settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema
                  | XmlSchemaValidationFlags.ProcessInlineSchema
                  | XmlSchemaValidationFlags.ReportValidationWarnings;
              settings.Schemas.Add(null, xsdFilePath);
              settings.Schemas.Compile();
  
              settings.ValidationEventHandler += (sender, args) =&gt;
              {
                  if (args.Severity == XmlSeverityType.Error)
                  {
                      Errors += args.Message + "\n";
                  }
              };
  
              using (var reader = XmlReader.Create(xmlFilePath, settings))
              {
                  while (reader.Read()) { }
              }
  
              message = Errors ?? string.Empty;
              return string.IsNullOrEmpty(Errors);
          }
          catch (Exception e)
          {
              message = "# error validating xml file: " + e.Message;
              return false;
          }
      }
  }
  </code></pre>
  
  <p>Somehow it seems i have to specify the path of the included XSD File but i have no idea where.</p>
  
  <p>The error occurs at <code>settings.Schemas.Compile();</code> , where it says that the type "MY_AMOUNT" is not declared. I read about custom XmlResolvers but to be honest i didn't get that working.</p>
  
  <p>If this is important for an answer: The xsd files are always located in the same directory!</p>
  
  <p>The method is called likes this:</p>
  
  <pre><code>string msg = string.Empty;
  string basedir = @"C:\Temp";
  string xml = Path.Combine(basedir, "XML_FILE.xml");
  string xsd = Path.Combine(basedir, "MAIN.xsd");
  
  if (XmlUtils.ValidateAgainstXSD(xml, xsd, ref msg))
  {
      // do some work
  }
  else
  {
      Console.WriteLine(msg);
  }
  
  Console.ReadLine();
  </code></pre>
  
  <p>Any help is highly appreciated - Thank you!</p>
  
  <h2><strong>UPDATE 2016-12-05:</strong></h2>
  
  <p>I wrote my own XmlUrlResolver, to see what happens behind the scenes:</p>
  
  <pre><code>internal class XUrlResolver : XmlUrlResolver
  {
      public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
      {
          return base.GetEntity(absoluteUri, role, ofObjectToReturn);
      }
  
      public override Uri ResolveUri(Uri baseUri, string relativeUri)
      {
          return base.ResolveUri(baseUri, relativeUri);
      }
  }
  </code></pre>
  
  <p>And the i just try to do:</p>
  
  <pre><code>XmlSchemaSet xset = new XmlSchemaSet();
  xset.XmlResolver = new XUrlResolver();
  xset.Add("", xsdFilePath);
  xset.Compile();
  </code></pre>
  
  <p>What happens now (on line <code>xset.Add</code>):</p>
  
  <ol>
  <li><code>XmlUrlResolver.ResolveUri(null,"C:\\Temp\\MAIN.XSD")</code> --> <code>{file:///C:/Temp/MAIN.xsd}</code></li>
  <li><code>XmlUrlResolver.ResolveUri(null,"C:\\Temp\\MAIN.XSD")</code> --> <code>{file:///C:/Temp/MAIN.xsd}</code></li>
  <li><code>XmlUrlResolver.GetEntity({file:///C:/Temp/MAIN.xsd})</code> --> Filestream to MAIN.xsd</li>
  <li><code>XmlUrlResolver.ResolveUri({file:///C:/Temp/MAIN.xsd},"TYPES.XSD")</code> --> <code>{file:///C:/Temp/TYPES.xsd}</code></li>
  <li><code>XmlUrlResolver.GetEntity({file:///C:/Temp/TYPES.xsd})</code> --> Filestream to TYPES.xsd</li>
  </ol>
  
  <p>Looks good to me (except the first 2 Calls are equal!?!) - the path to TYPES.XSD is resolved as it should.</p>
  
  <p>Nevertheless, <code>xset.Compile()</code> throws an Exception: "Type MY_AMOUNT is not declared"</p>
  
  <p>And i have no idea why :/ </p>