开发者

Using XSLT document() on a dynamicly generated XML in PHP

In my XSLT file. I use the document() function

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

an开发者_如何学God that works but if I try to link a PHP script that generate the XML dynamically,

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

I get a

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

Which consist of the < from <?php

It looks like the XSLTProcessor isn't requesting the file like via a HTTP request so it's not executed by Apache / PHP.

I know I could simply include that XML structure to my main XML but I'm trying to avoid this... until someone tell me there is no other way.

Thank you!


Right the document() function just reads a file off the disk, it does not make an HTTP request. So the PHP doesn't execute.

You'll have to use an URL instead of just the filename as the argument to your document() function.

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

I believe that using an URL in this way is a common feature in most XSLT processors, but I have not tested it with PHP, so your mileage may vary.


Since I stumbled upon this post with the help of a famous search engine when looking for a solution for a similar problem, here is what I found out so far. My aim was to have a layout.xml file which contains some XHTML layout and fill it with data from an data.xml tree generated by PHP (but not saved to disk) via XSL transformations.

It seems that you cannot import a dynamically generated XML directly in your XSLT file without saving it on disk or including it in the XSL tree. A solution seems to be to use two xsl transformations on your data.xml:

  1. Generate your data.xml which contains your data via php.
  2. Then use an XSL transformation to generate an XML which transforms your data.xml into an data.xsl (first transformation) - that data.xsl need to be so structured to apply its data to the layout.xml as needed (see next step)
  3. Use that data.xsl on your layout.xml to fill it with data (second transformation).

A blog-post [though in german language] describing that in more detail can be found here: xsl als Templatesystem

It may be a little cheating, since your data.xsl is a variant of your original XSL with the data-structure included. However, it seems to be more elegant, since you could probably create a generic first-transformation-xsl file (which needs to be saved to disk only once) and re-use it. I don't know yet if there is room for optimization since I haven't worked with XSLT much until now.


I achieve success with xslt document() function and php by simply using CURL to get XML (static or dynamic). So my URL is to a PHP script (proxy) that CURLs an XML resource somewhere. Something like this for getting an RSS formatted XML doc

<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">
    ...


If the first argument of the document() function is a relative URI, this is resolved off the base-uri of the second argument. If there is no second argument, then the base URI of the XSLT stylesheet containing the call to the document() function is used.

Here is an excerpt from the W3C XSLT spec.:

"The URI reference may be relative. The base URI (see [3.2 Base URI]) of the node in the second argument node-set that is first in document order is used as the base URI for resolving the relative URI into an absolute URI. If the second argument is omitted, then it defaults to the node in the stylesheet that contains the expression that includes the call to the document function. Note that a zero-length URI reference is a reference to the document relative to which the URI reference is being resolved; thus document("") refers to the root node of the stylesheet; the tree representation of the stylesheet is exactly the same as if the XML document containing the stylesheet was the initial source document."

This works well when the XSLT stylesheet does have a URI (file url or http url). However, a dynamically generated stylesheet is in memory and has no base URI. In this case a relative URI as the first and only argument of the document() function cannot be resolved successfully.

The solution is to provide the complete (absolute) URI of the XML document.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜