PHP 5.3.3 не может проверить XML на соответствие вложенным XSD - PullRequest
2 голосов
/ 20 октября 2010

После обновления с PHP 5.2.8 до 5.3.3 новая функция libxml_disable_entity_loader(false), похоже, не работает в Windows через командную строку до PHP-файла на сетевом ресурсе. В частности, DOMDocument::schemaValidate() завершается ошибкой с файлами XSD, которые содержат несколько уровней вложенных include () в другие файлы XSD в общей сетевой папке.

Приведенный ниже пример заставляет меня поверить, что вызов функции libxml_disable_entity_loader(false) не учитывается в PHP с файлами XSD, которые содержат несколько уровней вложенных XSD include ().

Я что-то здесь упускаю или вы думаете, что это ошибка в PHP или, возможно, libxml?

для репликации:

Тест 1 (успех):

"C:\PHP\5.3.3\php.exe" -c "C:\PHP\5.3.3\php.ini" "C:\Temp\validate.php"
  • В приведенном выше примере командной строки Windows используется жестко заданный путь, а не общая папка Windows.
  • Он успешно отразит «передачу» как в PHP 5.2.8, так и в PHP 5.3.3.

Тест 2 (сбой):

"C:\PHP\5.3.3\php.exe" -c "C:\PHP\5.3.3\php.ini" "\\192.168.82.99\Deployment\Temp\validate.php"
  • Щелкните правой кнопкой мыши диск C:> Свойства> Общий доступ> Новый общий ресурс> Имя общего ресурса: «Развертывание»
  • Измените IP-адрес в приведенном выше примере командной строки, чтобы он соответствовал вашему локальному компьютеру.
  • В приведенном выше примере командной строки Windows используются те же файлы, но через общую папку Windows.
  • В PHP 5.2.8 это будет эхо "пройдено".
  • В PHP 5.3.3 он будет отображать «сбой» и выдаст следующие предупреждения PHP о «не удалось загрузить внешнюю сущность» и «не удалось загрузить документ»:

Запуск приведенного выше примера командной строки в PHP 5.3.3 дает:

Warning: DOMDocument::schemaValidate(): I/O warning : failed to load external entity "/192.168.82.99/DEPLOYMENT/Temp/grandparent.xsd" in \\192.168.82.99\DEPLOYMENT\Temp\validate.php on line 8
Warning: DOMDocument::schemaValidate(): Element '{http://www.w3.org/2001/XMLSchema}include': Failed to load the document '/192.168.82.99/DEPLOYMENT/Temp/grandparent.xsd' for inclusion. in \\192.168.82.99\DEPLOYMENT\Temp\validate.php on line 8
Warning: DOMDocument::schemaValidate(): Invalid Schema in \\192.168.82.99\DEPLOYMENT\Temp\validate.php on line 8
failed

ФАЙЛЫ, КОТОРЫЕ НЕОБХОДИМО СДЕЛАТЬ:

Поместите все эти файлы в"C: \ Temp \" ( или измените пути в примерах командной строки )

validate.php

<?php
chdir(dirname(__FILE__));
libxml_disable_entity_loader(false);

$xmlDoc = new DomDocument();
$xmlDoc->load('sample.xml');

echo $xmlDoc->schemaValidate('child.xsd') ? 'passed' : 'failed'; 
?>

sample.xml

<?xml version="1.0"?>
<team mascot="cowboys" />

child.xsd

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified" >
  <!-- The include below works -->
  <xsd:include schemaLocation="parent.xsd" />
  <xsd:element name="team" type="baseTeam" />
</xsd:schema>

parent.xsd

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified" >
  <!-- The include below fails in PHP 5.3.3 even though libxml_disable_entity_loader(false) is called! -->
  <xsd:include schemaLocation="grandparent.xsd" />
  <xsd:complexType name="baseTeam">
     <xsd:attribute name="mascot" type="mascotNames" use="required" />
  </xsd:complexType>
</xsd:schema>

grandparent.xsd

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified" >
  <xsd:simpleType name="mascotNames">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="bengals" />
      <xsd:enumeration value="cowboys" />
      <xsd:enumeration value="patriots" />
    </xsd:restriction>
  </xsd:simpleType>
</xsd:schema>

1 Ответ

2 голосов
/ 13 марта 2011
$dir = dirname(__FILE__) . '/sources/';
$file = $dir . 'data.xml';
$xml = file_get_contents($file);

$doc = new DOMDocument;
$doc->documentURI = $file;
$doc->loadXML($xml);
$doc->xinclude();

echo $doc->schemaValidate($dir . 'child.xsd') ? 'passed' : 'failed'; 
...