/** * Generates the processing chain. * * @author Noah Fontes <*****@*****.**> * @since 1.0.0 */ protected static function createProcessors() { self::$processors = array(); self::$processorCount = 0; foreach (self::$chain as $file) { $processorImpl = new AgaviXmlConfigDomDocument(); $processorImpl->load(AgaviConfig::get('core.agavi_dir') . '/config/schematron/' . $file); $processor = new AgaviXmlConfigXsltProcessor(); $processor->importStylesheet($processorImpl); self::$processors[] = $processor; self::$processorCount++; } }
/** * Validate the document against the given list of Schematron files. * * @param AgaviXmlConfigDomDocument The document to act upon. * @param string The environment name. * @param string The context name. * @param array An array of file names to validate against. * * @author David Zülke <*****@*****.**> * @author Noah Fontes <*****@*****.**> * @since 0.11.0 */ public static function validateSchematron(AgaviXmlConfigDomDocument $document, $environment, $context, array $validationFiles = array()) { if (AgaviConfig::get('core.skip_config_transformations', false)) { return; } // load the schematron processor $schematron = new AgaviXmlConfigSchematronProcessor(); $schematron->setNode($document); // set some info (config file path, context name, environment name) as params // first arg is the namespace URI, which PHP doesn't support. awesome. see http://bugs.php.net/bug.php?id=30622 for the sad details // we could use "agavi:context" etc, that does work even without such a prefix being declared in the stylesheet, but that would be completely non-XML-ish, confusing, and against the spec. so we use dots instead. $schematron->setParameters(array('agavi.config_path' => $document->documentURI, 'agavi.environment' => $environment, 'agavi.context' => $context)); // loop over all validation files. those are .sch schematron schemas, which we transform to an XSL document that is then used to validate the source document :) foreach ($validationFiles as $href) { if (!is_readable($href)) { throw new AgaviUnreadableException(sprintf('Schematron validation file "%s" for configuration file "%s" does not exist or is unreadable', $href, $document->documentURI)); } // load the .sch file try { $sch = new AgaviXmlConfigDomDocument(); $sch->load($href); } catch (DOMException $dome) { throw new AgaviParseException(sprintf('Schematron validation of configuration file "%s" failed: Could not load schema file "%s": %s', $document->documentURI, $href, $dome->getMessage())); } // perform the validation transformation try { $result = $schematron->transform($sch); } catch (Exception $e) { throw new AgaviParseException(sprintf('Schematron validation of configuration file "%s" failed: Transformation failed: %s', $document->documentURI, $e->getMessage())); } // validation ran okay, now we need to look at the result document to see if there are errors $xpath = $result->getXpath(); $xpath->registerNamespace('svrl', self::NAMESPACE_SVRL_ISO); $results = $xpath->query('/svrl:schematron-output/svrl:failed-assert/svrl:text'); if ($results->length) { $errors = array('Failed assertions:'); foreach ($results as $result) { $errors[] = $result->nodeValue; } $results = $xpath->query('/svrl:schematron-output/svrl:successful-report/svrl:text'); if ($results->length) { $errors[] = ''; $errors[] = 'Successful reports:'; foreach ($results as $result) { $errors[] = $result->nodeValue; } } throw new AgaviParseException(sprintf('Schematron validation of configuration file "%s" failed:' . "\n\n%s", $document->documentURI, implode("\n", $errors))); } } }