title: Speeding up XML schema validations of a batch of XML files against the same XML schema (XSD)
body: <p>I would like to speed up the process of validating a batch of XML files against the same single XML schema (XSD). Only restrictions are that I am in a PHP environment.</p>
  
  <p>My current problem is that the schema I would like to validate against includes the fairly complex xhtml schema of 2755 lines (http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd).
  Even for very simple data this takes a long time (around 30 seconds pr. validation).
  As I have thousands of XML files in my batch, this doesn't really scale well.</p>
  
  <p>For validating the XML file I use both of these methods, from the standard php-xml libraries.</p>
  
  <ul>
  <li>DOMDocument::schemaValidate</li>
  <li>DOMDocument::schemaValidateSource</li>
  </ul>
  
  <p>I am thinking that the PHP implementation fetches the XHTML schema via HTTP and builds some internal representation (possibly a DOMDocument) and that this is thrown away when the validation is completed. I was thinking that some option for the XML-libs might change this behaviour to cache something in this process for reuse.</p>
  
  <p>I've build a simple test setup which illustrates my problem:</p>
  
  <p><a href="http://pastebin.com/jetD110d" rel="noreferrer"><strong>test-schema.xsd</strong></a></p>
  
  <pre><code>&lt;xs:schema attributeFormDefault="unqualified"
      elementFormDefault="qualified"
      targetNamespace="http://myschema.example.com/"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:myschema="http://myschema.example.com/"
      xmlns:xhtml="http://www.w3.org/1999/xhtml"&gt;
      &lt;xs:import
          schemaLocation="http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd"
          namespace="http://www.w3.org/1999/xhtml"&gt;
      &lt;/xs:import&gt;
      &lt;xs:element name="Root"&gt;
          &lt;xs:complexType&gt;
              &lt;xs:sequence&gt;
                  &lt;xs:element name="MyHTMLElement"&gt;
                      &lt;xs:complexType&gt;
                          &lt;xs:complexContent&gt;
                              &lt;xs:extension base="xhtml:Flow"&gt;&lt;/xs:extension&gt;
                          &lt;/xs:complexContent&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><a href="http://pastebin.com/5cSD5BR2" rel="noreferrer"><strong>test-data.xml</strong></a></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;Root xmlns="http://myschema.example.com/" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://myschema.example.com/ test-schema.xsd "&gt;
    &lt;MyHTMLElement&gt;
      &lt;xhtml:p&gt;This is an XHTML paragraph!&lt;/xhtml:p&gt;
    &lt;/MyHTMLElement&gt;
  &lt;/Root&gt;
  </code></pre>
  
  <p><a href="http://pastebin.com/cUAEJh95" rel="noreferrer"><strong>schematest.php</strong></a></p>
  
  <pre><code>&lt;?php
  $data_dom = new DOMDocument();
  $data_dom-&gt;load('test-data.xml');
  
  // Multiple validations using the schemaValidate method.
  for ($attempt = 1; $attempt &lt;= 3; $attempt++) {
      $start = time();
      echo "schemaValidate: Attempt #$attempt returns ";
      if (!$data_dom-&gt;schemaValidate('test-schema.xsd')) {
          echo "Invalid!";
      } else {
          echo "Valid!";
      }
      $end = time();
      echo " in " . ($end-$start) . " seconds.\n";
  }
  
  // Loading schema into a string.
  $schema_source = file_get_contents('test-schema.xsd');
  
  // Multiple validations using the schemaValidate method.
  for ($attempt = 1; $attempt &lt;= 3; $attempt++) {
      $start = time();
      echo "schemaValidateSource: Attempt #$attempt returns ";
      if (!$data_dom-&gt;schemaValidateSource($schema_source)) {
          echo "Invalid!";
      } else {
          echo "Valid!";
      }
      $end = time();
      echo " in " . ($end-$start) . " seconds.\n";
  }
  </code></pre>
  
  <p>Running this schematest.php file produces the following output:</p>
  
  <pre><code>schemaValidate: Attempt #1 returns Valid! in 30 seconds.
  schemaValidate: Attempt #2 returns Valid! in 30 seconds.
  schemaValidate: Attempt #3 returns Valid! in 30 seconds.
  schemaValidateSource: Attempt #1 returns Valid! in 32 seconds.
  schemaValidateSource: Attempt #2 returns Valid! in 30 seconds.
  schemaValidateSource: Attempt #3 returns Valid! in 30 seconds.
  </code></pre>
  
  <p>Any help and suggestions on how to solve this issue, are very welcomed!</p>