PHP Conference Japan 2024

XSLTProcessor::setParameter

(PHP 5, PHP 7, PHP 8)

XSLTProcessor::setParameter设置参数值

描述

public XSLTProcessor::setParameter(string $namespace, string $name, string $value): bool
public XSLTProcessor::setParameter(string $namespace, array $options): bool

设置一个或多个参数的值,这些参数将在随后使用 XSLTProcessor 进行转换时使用。如果样式表中不存在该参数,则将忽略它。

参数

namespace

XSLT 参数的命名空间 URI。

name

XSLT 参数的本地名称。

value

XSLT 参数的新值。

options

name => value 对的数组。

返回值

成功时返回 true,失败时返回 false

错误/异常

如果任何参数包含空字节,则抛出 ValueError

变更日志

版本 描述
8.4.0 现在,如果任何参数包含空字节,则会抛出 ValueError,而不是静默截断。
8.4.0 现在可以设置包含单引号和双引号的参数值。在 PHP 8.4.0 之前,这会导致警告。

示例

示例 #1 转换前更改所有者

<?php

$collections
= array(
'Marc Rutkowski' => 'marc',
'Olivier Parmentier' => 'olivier'
);

$xsl = new DOMDocument;
$xsl->load('collection.xsl');

// 配置转换器
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); // 附加 xsl 规则

foreach ($collections as $name => $file) {
// 加载 XML 源
$xml = new DOMDocument;
$xml->load('collection_' . $file . '.xml');

$proc->setParameter('', 'owner', $name);
$proc->transformToURI($xml, 'file:///tmp/' . $file . '.html');
}

?>

参见

添加注释

用户贡献的注释 6 条注释

1
Lennaert van der Linden
16 年前
[由 nielsdos 编辑:从 PHP 8.4.0 开始,这不再正确]

如果值同时包含单引号和双引号,则不会设置参数。转换文档时会显示警告。

PHP Warning: XSLTProcessor::transformToXml(): 无法创建 XPath 表达式(字符串同时包含单引号和双引号)
2
richard at aggmedia dot net
15 年前
请注意,除非知道参数的名称,否则无法从 XSLTProcessor 中删除参数,并且(据我所知)无法获取当前参数的列表。

这意味着,除非您对每个参数调用 XSLTProcessor->removeParameter(),否则您无法重用具有不同参数的 XSLTProcessor,而要执行此操作,您需要知道所有当前已设置参数的名称。

我遇到这个问题是因为我们正在缓存 XSLTProcessor 以供重用,它们正在根据幻像参数输出内容(它们仍然来自之前的用途)。
1
brettz9
17 年前
看来 heinemann 的用法不正确,无法达到预期的结果。

此方法的目的是更改 XSL 样式表中的全局 <xsl:param> 值,而不是更改任何其他元素的属性。<xsl:param> 基本上允许您设置一个样式表,该样式表可以从外部(无需修改原始 XSL 文件)进行自定义(例如来自 PHP)。

这是一个用法示例(将起作用)

样式表

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="print_something" select="defaultstring"/>
<xsl:template match="/mydoc">
<p style="color:red;">Printed parameter: <xsl:value-of select="$print_something"/></p>
</xsl:template>
</xsl:stylesheet>

脚本

<?php
$dom
= new DOMDocument();
$xsl = new XSLTProcessor;
$xsl->setParameter( '', 'print_something', "Now I've overridden the default!");
$style = realpath( "./my_stylesheet.xslt" );
$dom->load($style);
$xsl->importStyleSheet($dom);
$dom->loadXML('<mydoc></mydoc>');

$out = $xsl->transformToXML( $dom );

var_dump( '<pre>',
htmlentities( $out, ENT_QUOTES, 'utf-8' ),
$xsl->getParameter('', 'print_something'),
'</pre>' );
?>

给出

string(5) "

"
string(143) "<?xml version="1.0"?>
<p style="color:red;">Printed parameter: Now I've overridden the default!</p>
"
string(32) "Now I've overridden the default!"
string(6) "

"

注意,目前添加命名空间将不起作用。目前唯一的选择是将第一个命名空间参数设置为空字符串(尽管您可以将带冒号的前缀添加到第二个名称参数中,以便为命名空间前缀的参数名称设置参数)。

参见 http://bugs.php.net/bug.php?id=30622
0
OrionI
17 年前
进一步研究后(参见 http://bugs.php.net/bug.php?id=41248),似乎是libxslt的不足,而不是PHP的问题,导致无法将DOMDocuments或DOMNodes作为参数传递。
0
Orion I
17 年前
我一直在尝试将DOMDocument对象作为参数传递,以便将大量数据填充到XML节点中,但似乎此函数无法做到这一点。我希望它能像.NET 2.0框架那样工作。(参见 http://msdn2.microsoft.com/en-us/library/
system.xml.xsl.xsltargumentlist.addparam.aspx)
但是,在查看PHP 5.2.1源代码`/php-5.2.1/ext/xsl/xsltprocessor.c`的604-650行后,似乎即使libxslt似乎支持它(参见 http://xmlsoft.org/XSLT/html/libxslt-variables.html
#xsltParseGlobalParam)

事实上,如果参数不完全符合预期,你将始终收到类似这样的警告:

XSLTProcessor::setParameter() 参数数量错误
-1
heinemann dot juergen at hjcms dot de
18年前
工作示例。

<?xml version = '1.0' encoding = 'utf-8' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
indent="yes"
encoding="ISO-8859-15"
doctype-system = "-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-public = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
/>
<xsl:template match="docs">
<html>
<head>
<title>
<xsl:text>示例</xsl:text>
</title>
</head>
<body>
<xsl:for-each select="block">
<div>
<xsl:value-of select="." />
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

------------------

<?php
$dom
= new DomDocument( '1.0', 'utf-8' );
$xsl = new XSLTProcessor;
$xsl->setParameter( 'block', 'xmlns', 'http://www.w3.org/1999/xhtml' );

$style = realpath( "./my_stylesheet.xslt" );
$dom->load( $style );
$xsl->importStyleSheet( $dom );

$dom->loadXML( '<docs>
<block>如何在php中设置xhtml Transitional命名空间</block>
<block>参见https://php.net</block>
</docs>'
);

$out = $xsl->transformToXML( $dom );

var_dump( '<pre>',
htmlentities( $out, ENT_QUOTES, 'utf-8' ),
$xsl->getParameter( 'block', 'xmlns' ),
$xsl->getParameter( 'docs', 'xmlns' ),
'</pre>' );

?>
To Top