升级PHP版本后xsl:include失败;是libxml / libxslt版本不匹配的问题?

时间:2011-02-02 23:22:06

标签: php libxml2 libxslt

我正在使用windows.php.net提供的预编译PHP二进制文件运行Windows XP。我从PHP 5.2.5升级到PHP 5.2.16,现在我的一些样式表中的xsl:include停止了工作。我连续测试了每个版本,发现它通过5.2.8开始工作,但在5.2.9+中不起作用。我现在为每个xsl:include收到以下三个错误。

Warning: XSLTProcessor::importStylesheet() [xsltprocessor.importstylesheet]: I/O warning : failed to load external entity "file%3A/C%3A/path/to/included/stylesheet.xsl" in ... on line 227

Warning: XSLTProcessor::importStylesheet() [xsltprocessor.importstylesheet]: compilation error: file file%3A//C%3A/path/to/included/stylesheet.xsl line 36 element include in ... on line 227

Warning: XSLTProcessor::importStylesheet() [xsltprocessor.importstylesheet]: xsl:include : unable to load file%3A/C%3A/path/to/included/stylesheet.xsl in ... on line 227

我认为这是因为找不到指定的文件。许多包含与正在转换的样式表位于同一目录中,并且路径中没有目录,即<xsl:include href="fileInSameDir.xsl">。有趣的是,在第一个和第三个错误中,它显示的文件://协议只有一个斜杠而不是正确的斜杠。我猜这就是问题所在。 (当我使用“file:/”对完整路径进行硬编码时,它会失败,但是当我用“file://”硬编码完整路径时,它会起作用。)但是什么可能导致这种情况? libxslt / libxml中的错误?我还发现libxml与libxslt编译的libxml版本之间存在明显的版本不匹配。

  

5.2.5
  libxml Version =&gt; 2.6.26
  libxslt针对libxml编译版本=&gt; 2.6.26

     

5.2.8

     

libxml Version =&gt; 2.6.32
  libxslt针对libxml编译版本=&gt; 2.6.32

     

===它在从5.2.9开始的版本中断===
  5.2.9
  libxml Version =&gt; 2.7.3
  libxslt针对libxml编译版本=&gt; 2.6.32

     

5.2.16
  libxml Version =&gt; 2.7.7
  libxslt针对libxml编译版本=&gt; 2.6.32

直到PHP 5.2.9,libxslt是针对PHP附带的相同版本的libxml编译的。但是从PHP 5.2.9开始,libxslt是针对旧版本的libxml编译的,而不是PHP中包含的版本。 这是分布式二进制文件的问题还是巧合?

为了测试这个,我想可以使用不同版本的libxml / libxslt构建PHP,以查看哪些组合有效或无效。不幸的是,我在Windows世界中脱离了我的元素,在Windows上构建PHP似乎超出了我的想法。

令人遗憾的是,我一直无法通过我的应用程序之外的示例重现此问题,因此我正在努力缩小范围并且无法提交特定的错误。

那么,你认为它是由

引起的吗?
  • 分布式二进制文件中的版本不匹配问题?
  • PHP 5.2.9中引入的错误?
  • libxml 2.7中引入了一个错误?
  • 别的什么?

我很难过。任何可以指向正确方向的想法都非常感谢。感谢。

1 个答案:

答案 0 :(得分:1)

此内容已提交为PHP bug #53965

正确使用file:// protocol表示完整的Windows路径必须有第三个连续的斜杠才能暗示localhost(即file:/// C:/ path)。我的应用程序错误地使用两个斜杠(即file:// C:/ path)。据推测,解析器只是简单地将URI标记为没有完整的错误检查,然后将重新组合的字符串传递给XSLT处理器,从而导致出现“file:/ C:/ path”。

解决我问题的两个选项:

  1. 添加第三个斜杠,或
  2. 完全删除“file://”协议,因为它们只是本地文件
  3. 即使我的代码最终不正确,我的混淆也源于这样一个事实,即没有生成错误,指出我的无效URI并且初始文件仍然成功加载。两个文件都应该加载,或者两个文件都不应该加载 - 不是一个加载而一个不加载,就像这样。