2010-10-16 71 views
2

在我的XSLT文件中。我用的是document()功能在PHP中动态生成的XML上使用XSLT文档()

<xsl:variable name="Publicity" select="document('./publicity.xml')" /> 

和作品,但如果我尝试链接生成动态的XML PHP脚本,

<xsl:variable name="Publicity" select="document('./publicity.php')" /> 

我得到一个

Warning: XSLTProcessor::transformToXml() [xsltprocessor.transformtoxml]: file:///C:/wamp/www/XSLT/test.php:3: parser error : Start tag expected, '<' not found in ... on line ... 

组成如下的< from <?php

它看起来像X SLTProcessor不像通过HTTP请求那样请求文件,所以它不会被Apache/PHP执行。

我知道我可以简单地将XML结构包含到我的主XML中,但我试图避免这种情况......直到有人告诉我没有其他方式。

谢谢!

+0

它根本不清楚。什么是您的源XML文件(请提供一个简单的例子)。什么是您的XSLT样式表(请提供一个简单示例)。 “如果我尝试链接动态生成XML的PHP​​脚本”,您是什么意思?这些例子必须完整但很少,并且必须重现问题。 – 2010-10-16 16:36:07

+0

@Dimitre:当我使用'document()'指向一个'XML'文件时,如果我使用'document()'来访问一个'PHP'脚本(PHP可以生成XML fyi),我得到一个错误。比尔说,document()从磁盘读取文件,所以'PHP'不会执行,所以我得到一个错误。我想没有办法真的做到这一点。 – Cybrix 2010-10-16 23:48:50

+0

请参阅我的回答以获取解释和解决方法。 – 2010-10-17 00:02:06

回答

3

正确的文档()函数只是从磁盘读取文件,它不会发出HTTP请求。所以PHP不执行。

您将不得不使用URL而不是文件名作为document()函数的参数。

<xsl:variable name="Publicity" 
    select="document('http://example.com/publicity.php')" /> 

我认为,以这种方式使用的URL在大多数XSLT处理器一个共同的特点,但我没有用PHP进行测试,所以你的里程可能会有所不同。

+0

因为未知原因,它不适用于PHP。页面刚刚超时。我没有犯任何错误的网址。我想这不能在PHP/XSLTProcessor中完成。谢谢 – Cybrix 2010-10-16 17:15:21

+0

然后,您可能需要将PHP脚本作为离线任务运行,以便定期创建XML文件,以便您的XSLT脚本可以读取它。对不起,你不能从这里到达。 :) – 2010-10-16 17:40:17

0

如果第一个参数为the document()函数是一个相对URI,它将在第二个参数的base-uri之外解决。如果没有第二个参数,则使用包含调用document()函数的XSLT样式表的基本URI。

下面是从W3C XSLT spec的摘录:

“的URI引用可以相 基URI(见[3.2基础URI])的 在第二个参数 的节点。如果第二个参数 被省略,则它默认为包含的样式表中的 节点。 如果第二个参数 被忽略,则它将默认为包含的样式表中的 节点包含对文档函数调用 的表达式。请注意, 零长度URI引用是 对文档的引用,相对于 ,URI引用正在解析为 ;因此文档(“”)是指 样式表的根节点;样式表 的 树表示是完全一样的,如果含有的样式表将XML 文件是 初始源文档。”

这种运作良好时XSLT样式表确实有URI(文件URL或http url)。但是,动态生成的样式表在内存中并且没有基本URI。在这种情况下,作为document()函数的第一个也是唯一参数的相对URI无法成功解析。

解决方案是提供XML文档的完整(绝对)URI。

+0

而我的解决方案是什么?谢谢 – Cybrix 2010-10-18 01:05:52

+0

@Cybrix:正如我所说:“解决方案是提供XML文档的完整(绝对)URI”。 – 2010-10-18 01:08:31

+0

我明白了。但这就是Bill Karwin所建议的,不幸的是PHP的XSLTProcessor不能进行转换。尽管谢谢你的回答。 – Cybrix 2010-10-18 01:24:31

1

由于我在寻找类似问题的解决方案时偶然发现了一篇着名搜索引擎的帮助文章,这里是我发现的内容。我的目标是创建一个layout.xml文件,其中包含一些XHTML布局,并使用由PHP生成的data.xml树(但不保存到磁盘)中的数据通过XSL转换填充数据。

看来您不能将动态生成的XML直接导入到XSLT文件中,而无需将其保存在磁盘上或将其包含在XSL树中。解决方案似乎是在data.xml中使用两个xsl转换:

  1. 通过php生成包含您的数据的data.xml。
  2. 然后使用XSL转换生成一个将您的data.xml转换为data.xsl(第一个转换)的XML - data.xsl需要如此构造以便根据需要将其数据应用于layout.xml(请参阅下一步)
  3. 在你的layout.xml中使用data.xsl来填充数据(第二次转换)。

一个博客,文章[尽管在德语]描述了更详细可以在这里找到:xsl als Templatesystem

这可能是有点欺骗,因为你的data.xsl是你原来的XSL的一个变种包括数据结构。但是,它似乎更优雅,因为您可能会创建一个通用的first-transformation-xsl文件(只需将其保存到磁盘一次)并重新使用它。我还不知道是否有优化的空间,因为到现在为止我还没有用过XSLT。

1

我通过简单地使用CURL获取XML(静态或动态),实现了xslt document()函数和php的成功。因此,我的URL是一个PHP脚本(代理),它可以在某处找到一个XML资源。类似这样的获取RSS格式的XML文档

<xsl:variable name="homeUrl" select="http://mydomain.tld/"/> 
<xsl:variable name="xmlUrl" select="http://domain.tld/feed.rss"/> 
<xsl:variable name="includeXML" select="document(concat($homeUrl,'api/proxy.php?url=',$xmlUrl))"/> 

<xsl:for-each select="$includeXML/rss/channel/item"> 
    ... 
+0

谢谢!我会做一些测试,看看它是否适合我。 – Cybrix 2012-06-18 19:59:51