在 XSL 中定义 PHP-Function 并调用它。可能的?如何?

Posted

技术标签:

【中文标题】在 XSL 中定义 PHP-Function 并调用它。可能的?如何?【英文标题】:Define PHP-Function in XSL and calling it. Possible? How? 【发布时间】:2011-03-17 08:09:14 【问题描述】:

正如标题所说:是否可以在 XSL 文档中编写 php 函数并在之后调用它?

我没有案例,我想在哪里做。这只是我在学习 XSL 时想到的。

在 XSL 中,您可以编写如下内容:

<xsl:processing-instruction name="php">
   ...some php...
</xsl>

PHP 代码将在您呈现的页面中运行。是否可以创建例如处理指令中的 PHP 函数并稍后调用它(在同一模板中)?

伪样本:

<xsl:template>

   <xsl:processing-instruction name="php">
      ...some php processing $foo...
   </xsl>

   <xsl:variable name="foo" select="xpath/node">

   <xsl:value-of select="call-php-function-with-$foo"/>

</xsl>

我期待您的解决方案/方法 :)

克里斯

【问题讨论】:

如果您使用 XSL 作为模板,我建议您改用 Smarty。它具有更好的性能,您可以在模板中执行 PHP。 smarty.net 这并不能真正帮助我们讨论这个话题。这是关于 XSLT 的。我不知道聪明,但就像我在第一印象中看到的那样,这是完全不同的东西。还是谢谢你。 好问题 (+1)。有关解释和可能的替代解决方案,请参阅我的答案。 【参考方案1】:

我认为所选答案指向错误的方向。无需使用 FXSL,您可以轻松地将用其他语言编写的扩展添加到 XSLT - 例如带有 Xalan 的 Jython 或 javascript,带有大多数 Java 处理器的 Java 等。

对于 PHP,如果您在 PHP 脚本中进行 XSLT 处理(而不是从 Ant 或其他东西中运行 Xalan),那么使用 XSLTProcessor::registerPHPFunctions 非常容易,它允许您编写类似的东西

$xsl = <<<EOF
...
<xsl:value-of select="php:function('myFunc', . )"/> 
...
EOF;

function myFunc( $node ) 
//etc

当然,只有 PHP 脚本才能正确处理 XSL。

这一切都非常清楚地记录在 http://www.php.net/manual/en/xsltprocessor.registerphpfunctions.php

【讨论】:

fritzfromlondon:您需要仔细阅读所选答案-实际上它说可以编写此类函数,前提是这符合编写扩展函数的规则。请编辑您的答案并删除第一句中的错误陈述。【参考方案2】:

这是可以做到的(记住 Dimitre,如果他问的是 PHP,他几乎肯定仅限于 XSLT 1.0,而 FXSL 并不是他所追求的)。

首先,如果您打算自己编写 PHP,并将其用作文档处理流程的一部分,那么这可能是一个糟糕的语言选择。如果您只想使用您自己的一些 PHP 函数或有用的库函数(如 preg_replace)稍微扩展 XSL 的功能,因此您可以从您的 XSLT 中调用它们,如果您知道那些是绝对没问题的预先设置:您将 PHP 函数导出到 XSLT,然后从那里调用它们。

如果您想要执行的代码对于每个文档都不同,它会变得更加困难(即,对于您尝试处理的包含 PHP 的文档中的处理指令,并且您希望在评估您的文档时执行 XSLT 脚本处理指令)。尝试将函数分解为已知集合,然后从 PHP 中调用它们,但如果你不能并且仍然想尝试,那就是hackery。

(我假设您了解 PHP 将函数导出到 XSLT 的方式:您制作了一些普通的 PHP 函数,使用 registerPHPFunctions 将它们导出到 XSLT 脚本,然后它们只是将它们作为 XSLT 中的函数调用。这是一个很好的 -走过的路;查看文档。)

回到从 XSLT 脚本执行文档 PI 中的 PHP 代码。

(我自己没有做过,但实施起来应该不会那么难。)我相信不可能一次性完成。您必须调用XSLT 处理器,并且每当您点击要运行的PHP 时,放入一个标记标签(例如&lt;phpmarker md5ofcode="php:md5(...)"&gt;)并将代码传回给调用PHP。哈克,但可能适合生活的方法是将它放在 xsl:message 中并从 PHP 中的自定义处理程序中捕获它。

当第一次运行结束时,做一些字符串操作,在你抓取的每个代码块周围创建一个包装函数,评估该字符串以创建函数,将它们导出到 XSLT 引擎,然后重新调用第二个 XSLT 脚本将 cat 标记节点,并在其内容上调用 PHP。

丑吗?是的。您可能想解释为什么需要它,但应该可以(通过两次)使其工作。

编辑:又重读了几次你的问题,我越来越困惑。您确定要在您的 XSLT 中进行 PI 吗? PI 进入文档,解释如何处理它们。如果 PHP 打算放在 XSLT 文件中并且这不是错字,我想你可能会有点困惑,它只是 PHP 的 registerPHPFunctions 的普通应用程序。您只需将 PHP 放在一个单独的文件中并从 XSLT 中调用它,考虑到 XSLT 脚本在大到足以拆分为两个文件之前不必包含太多功能,这并不是一个巨大的负担。

【讨论】:

尼古拉斯·威尔逊,我明白你的困惑。 1)。在 XSLT 1.0 中,不能编写 函数(用 XSLT 编写)。在 XSLT 2.0 及更高版本中有这样的功能,使用 xsl:function 指令; 2) FXSL 有适用于 XSLT 1.0 和 XSLT 2.0 的版本both。在我的回答中,我提到 OP 可以使用 FXSL(与使用 XSLT 1.0 的其他任何人一样)。【参考方案3】:

在 XSLT 1.0 中,不可能调用用另一种语言编写的函数,除非这些函数是按照特定 XSLT 处理器对扩展函数的要求编写的并且在启动转换时可用的扩展函数集。

可以通过调用或应用模板来模拟功能。

在 XSLT 2.0 中可以使用 &lt;xsl:function&gt; 指令编写函数在 XSLT 中。然后可以在任何其他 XSLT 指令的select 属性中指定的任何 XPath 表达式中引用这些函数。

在 XSLT 1.0 和 XSLT 2.0 中甚至可以实现 高阶函数 (HOF)。这就是 FXSL library(完全用 XSLT 编写)所做的。

【讨论】:

@fritzfromlondon:是的,您的评论证实了您在这个答案中发现的奇怪之处——php:function() 是一个扩展函数,它不是用 XSLT 本身编写的. 我认为这个答案是错误的-您自己承认可以使用扩展功能。它也可以在 PHP 中完成。作为参考,我在下面的单独答案中给出了一些建议。 对不起@Dimitre Novatches,没有意识到你已经回复了,正在重写我的评论。我认为这是不必要的迂腐——ChrisBenyamin 只是想在他的 XSLT 中使用一些 PHP 函数,我认为他不在乎它们是否是扩展。 @fritzfromlondon:这个答案清楚地表明调用扩展函数(用另一个 PL 编写的函数)是可能的,前提是“这些是按照特定 XSLT 处理器对扩展函数的要求编写的我>”。答案没有错,觉得很满意,被采纳了。 嗯,我认为这是错误的,因为它指向 FXSL,而不是指向编写 PHP 扩展的文档,这正是他所要求的。无论如何,如果其他人偶然发现了这些链接,我已经添加了这些链接。

以上是关于在 XSL 中定义 PHP-Function 并调用它。可能的?如何?的主要内容,如果未能解决你的问题,请参考以下文章

在 XSLT 2.0 中定义变量时使用 xsl:copy-of

xsl:function 定义的函数可以替代 xpath 3.0 内联函数吗?

XSL 从另一个文档评估动态 XPATH

XSLT:如何将节点值传递给自定义 xsl:function ?

XSL 节点集:不按名称查找子元素

内网服务器离线编译安装mysql5.7并调优