Мне интересно, можно ли проверить xml на несколько схем в PHP или мне нужно как-то объединить мои схемы.Можно ли проверить XML на несколько схем в PHP?
Благодарим за ответ!
Мне интересно, можно ли проверить xml на несколько схем в PHP или мне нужно как-то объединить мои схемы.Можно ли проверить XML на несколько схем в PHP?
Благодарим за ответ!
Я решил свою проблему с помощью простого PHP скрипта:
$mainSchemaFile = dirname(__FILE__) . "/main-schema.xml";
$additionalSchemaFile = 'second-schema.xml';
$additionalSchema = simplexml_load_file($additionalSchemaFile);
$additionalSchema->registerXPathNamespace("xs", "http://www.w3.org/2001/XMLSchema");
$nodes = $additionalSchema->xpath('/xs:schema/*');
$xml = '';
foreach ($nodes as $child) {
$xml .= $child->asXML() . "\n";
}
$result = str_replace("</xs:schema>", $xml . "</xs:schema>", file_get_contents($mainSchemaFile));
var_dump($result); // merged schema in form XML (string)
Но это возможно только благодаря тому, что схемы одинаковы - т.е.
<xs:schema xmlns="NAMESPACE"
targetNamespace="NAMESPACE"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
в обоих файлах ,
Учитывая, что метод DOMDocument::schemaValidate
получает путь к файлу схемы в качестве параметра, я бы сказал, что вам просто нужно вызвать этот метод несколько раз: один раз для каждой из ваших схем.
См. Также DOMDocument::schemaValidateSource
, если у вас есть ваши схемы в строках PHP; идея (и ответ) будет такой же: просто вызовите метод несколько раз.
Разработчики Syfmony2 решили эту проблему. Это не Freakin' чистое, но будет делать:
function validateSchema(\DOMDocument $dom)
{
$tmpfiles = array();
$imports = '';
foreach ($this->schemaLocations as $namespace => $location) {
$parts = explode('/', $location);
if (preg_match('#^phar://#i', $location)) {
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
if ($tmpfile) {
file_put_contents($tmpfile, file_get_contents($location));
$tmpfiles[] = $tmpfile;
$parts = explode('/', str_replace('\\', '/', $tmpfile));
}
}
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
$location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
$imports .= sprintf(' <xsd:import namespace="%s" schemaLocation="%s" />' . PHP_EOL, $namespace, $location);
}
$source = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns="http://symfony.com/schema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://symfony.com/schema"
elementFormDefault="qualified">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
$imports
</xsd:schema>
EOF
;
$current = libxml_use_internal_errors(true);
$valid = $dom->schemaValidateSource($source);
foreach ($tmpfiles as $tmpfile) {
@unlink($tmpfile);
}
if (!$valid) {
throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors()));
}
libxml_use_internal_errors($current);
}
Основной файл схема должен содержать включаемый тег для каждого файла ребенок схемы. Например:
<xs:include schemaLocation="2nd_schema_file.xsd"/>
Это было также мое предположение, но к сожалению оно не работает. Думаю, мне придется объединить мои схемы. –