問題描述
我想知道是否以及如何向 XSLT 處理器注冊一個 PHP 用戶空間函數,該函數不僅可以獲取節點數組,還可以返回它?
I wonder if and how it is possible to register a PHP userspace function with the XSLT processor that is able not only to take an array of nodes but also to return it?
現在 PHP 抱怨使用通用設置將數組轉換為字符串:
Right now PHP complains about an array to string conversion using the common setup:
function all_but_first(array $nodes) {
array_shift($nodes);
shuffle($nodes);
return $nodes;
};
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStylesheet($xslDoc);
$buffer = $proc->transformToXML($xmlDoc);
要轉換的 XMLDocument ($xmlDoc
) 例如可以是:
The XMLDocument ($xmlDoc
) to transform can for example be:
<p>
<name>Name-1</name>
<name>Name-2</name>
<name>Name-3</name>
<name>Name-4</name>
</p>
在樣式表中是這樣調用的:
Within the stylesheet it's called like this:
<xsl:template name="listing">
<xsl:apply-templates select="php:function('all_but_first', /p/name)">
</xsl:apply-templates>
</xsl:template>
通知如下:
注意:數組到字符串的轉換
Notice: Array to string conversion
我不明白為什么如果函數得到一個數組作為輸入,它也不能返回一個數組?
I don't understand why if the function gets an array as input is not able to return an array as well?
我也在嘗試其他函數"名稱,因為我看到有 php:functionString
但到目前為止都嘗試過 (php:functionArray
, php:functionSet
和 php:functionList
) 不起作用.
I was also trying other "function" names as I've seen there is php:functionString
but all tried so far (php:functionArray
, php:functionSet
and php:functionList
) did not work.
在 PHP 手冊中,我可以返回另一個包含元素的 DOMDocument
,但是這些元素不再來自原始文檔.這對我來說沒有多大意義.
In the PHP manual it's written I can return another DOMDocument
containing elements, however then those elements aren't from the original document any longer. That does not make much sense to me.
推薦答案
對我有用的是返回一個 DOMDocumentFragment
而不是數組.因此,為了在您的示例中進行嘗試,我將您的輸入保存為 foo.xml
.然后我讓 foo.xslt
看起來像這樣:
Something that works for me is to return an instance of DOMDocumentFragment
instead of an array. So to try it on your example, I saved your input as foo.xml
. Then I made foo.xslt
look like this:
<xsl:stylesheet version="1.0" xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:php="http://php.net/xsl">
<xsl:template match="/">
<xsl:call-template name="listing" />
</xsl:template>
<xsl:template match="name">
<bar> <xsl:value-of select="text()" /> </bar>
</xsl:template>
<xsl:template name="listing">
<foo>
<xsl:for-each select="php:function('all_but_first', /p/name)">
<xsl:apply-templates />
</xsl:for-each>
</foo>
</xsl:template>
</xsl:stylesheet>
(這主要只是您使用 xsl:stylesheet
包裝器來調用它的示例.)問題的真正核心,foo.php
:
(This is mostly just your example with a xsl:stylesheet
wrapper to invoke it.) And the real heart of the matter, foo.php
:
<?php
function all_but_first($nodes) {
if (($nodes == null) || (count($nodes) == 0)) {
return ''; // Not sure what the right "nothing" return value is
}
$returnValue = $nodes[0]->ownerDocument->createDocumentFragment();
array_shift($nodes);
shuffle($nodes);
foreach ($nodes as $node) {
$returnValue->appendChild($node);
}
return $returnValue;
};
$xslDoc = new SimpleXMLElement('./foo.xslt', 0, true);
$xmlDoc = new SimpleXMLElement('./foo.xml', 0, true);
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStylesheet($xslDoc);
$buffer = $proc->transformToXML($xmlDoc);
echo $buffer;
?>
重要的部分是調用 ownerDocument->createDocumentFragment()
以生成從函數返回的對象.
The important part being the call to ownerDocument->createDocumentFragment()
to make the object that gets returned from the function.
這篇關于如何使用 PHP 函數過濾選擇節點集?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!