PHP 5.3.3无法针对嵌套的XSD验证XML

时间:2010-10-20 18:44:25

标签: php xml xsd libxml2

从PHP 5.2.8升级到5.3.3后,新的libxml_disable_entity_loader(false)函数似乎无法通过命令行在Windows上运行到网络共享上的PHP文件。更具体地说,DOMDocument::schemaValidate()失败的XSD文件包含多层嵌套的include()到网络共享上的其他XSD文件。

下面的例子让我相信,PHP中没有使用包含多级嵌套XSD include()的XSD文件来调用libxml_disable_entity_loader(false)的函数。

我在这里遗漏了什么,或者你认为这是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 个答案:

答案 0 :(得分:2)

$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';