2010-04-30 4 views

ответ

1

Я решил свою проблему с помощью простого 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"> 

в обоих файлах ,

-1

Учитывая, что метод DOMDocument::schemaValidate получает путь к файлу схемы в качестве параметра, я бы сказал, что вам просто нужно вызвать этот метод несколько раз: один раз для каждой из ваших схем.

См. Также DOMDocument::schemaValidateSource, если у вас есть ваши схемы в строках PHP; идея (и ответ) будет такой же: просто вызовите метод несколько раз.

+0

Это было также мое предположение, но к сожалению оно не работает. Думаю, мне придется объединить мои схемы. –

1

Разработчики 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); 
} 
3

Основной файл схема должен содержать включаемый тег для каждого файла ребенок схемы. Например:

<xs:include schemaLocation="2nd_schema_file.xsd"/> 
Смежные вопросы