XSLTProcessor::transformToXml

(PHP 5, PHP 7, PHP 8)

XSLTProcessor::transformToXml转换为 XML

描述

public XSLTProcessor::transformToXml(object $document): string|null|false

使用 xsltprocessor::importStylesheet() 方法给出的样式表,将源节点转换为字符串。

参数

document

要转换的 DOMDocumentSimpleXMLElement 对象。

返回值

转换结果作为字符串,或在出错时为 false

范例

范例 #1 转换为字符串

<?php

// 加载 XML 源
$xml = new DOMDocument;
$xml->load('collection.xml');

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

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

echo $proc->transformToXML($xml);

?>

上面的示例将输出

Hey! Welcome to Nicolas Eliaszewicz's sweet CD collection!

<h1>Fight for your mind</h1><h2>by Ben Harper - 1995</h2><hr>
<h1>Electric Ladyland</h1><h2>by Jimi Hendrix - 1997</h2><hr>

参见

添加笔记

用户贡献笔记 11 笔记

6
werner@mollentze
17 年前
transformToXML 函数可以生成有效的 XHTML 输出 - 它遵循 <xsl:output> 元素的属性,该属性定义了输出文档的格式。

例如,如果您想要有效的 XHTML 1.0 Strict 输出,您可以在您的 XSL 样式表中为 <xsl:output> 元素提供以下属性值

<xsl:output
method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" />
5
lsoethout at hotmail dot com
18 年前
transformToXML 函数在元内容类型标签方面存在问题。它输出如下

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

这不是正确的 X(HT)ML,因为它以 '>' 而不是 '/>' 结束。

一个获得正确输出的方法是使用 transformToDoc 而不是 transformToXML,然后保存 HTML

$domTranObj = $xslProcessor->transformToDoc($domXmlObj);
$domHtmlText = $domTranObj->saveHTML();
7
Charlie Murder
14 年前
为了防止您的 xsl 文件自动添加

<?xml version="1.0"?>

同时保持输出为 xml,这对于验证过的严格 xhtml 文件来说是更好的选择,而不是指定输出为

<xsl:output method="xml" omit-xml-declaration="yes" />
3
michael dot weibel at tilllate dot com
14 年前
如果您从 transformToXML 方法中获取 "false",请使用 libxml_get_last_error() 或 libxml_get_errors() 来获取错误。
3
john
16 年前
如果您的 xsl 没有 <html> 标签。输出将包含 <?xml version="1.0"?>。要解决此问题,您可以在您的 xsl 样式表中添加以下内容

<xsl:output
method="html" />
6
zweibieren at yahoo dot com
13 年前
使用上面的代码,实体将从输出中省略。
症状是 &nbsp;
-- 应该与 UTF-8 编码一起使用 --
甚至没有到达 XSLTProcessor,更不用说通过它了。
经过大量的黑客攻击后,我发现了简单的解决方法
在 XSL 文件的 DOMDocument 中将 substituteEntities 设置为 true。
也就是说,用以下内容替换 xsl 文档的加载

<?php
$xsl
= new DOMDocument;
$xsl->substituteEntities = true; // <===添加的行
$xsl->load('collection.xsl');
?>

但是,当数据条目包含 HTML 实体引用时,这会失败。(某些数据库条目甚至可能包含用户生成的文本。)libxml 有一个偏执的习惯,即对任何未定义的实体抛出致命错误。解决方案:隐藏实体,以便 libxml 看不到它们。

<?php
function hideEntities($data) {
return
str_replace("&", "&amp;", $data);
}
?>

您可以将其添加到示例中,但定义一个函数将数据加载到 DOMDocument 中会更整洁。这样,您也不需要在 catalog.xsl 中声明实体。

<?php
// 为示例 #1 添加函数

/** 加载 XML 文件并创建一个 DOMDocument。
处理任意实体,即使是未定义的实体。
*/
function fileToDOMDoc($filename) {
$dom= new DOMDocument;
$xmldata = file_get_contents($filename);
$xmldata = str_replace("&", "&amp;", $xmldata); // 将传入 loadXML() 的 & 伪装起来
$dom->substituteEntities = true; // 将传出 transformToXML() 的 & 折叠起来
$dom->loadXML($xmldata);
return
$dom;
}

// 与示例 #1 进行比较,将结果转换为字符串

// 加载 XML 源文件
$xml = fileToDOMDoc('collection.xml');
$xsl = fileToDOMDoc('collection.xsl');

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

// 根据样式表 $xsl 转换 $xml
echo $proc->transformToXML($xml); // 转换数据
?>
3
Josef Hornych
9 年前
请注意,该方法的名称有点误导性,因为它不仅输出 XML,还输出处理器生成的任何字符串。 它应该更名为 transformToString。 因此,如果您的输出方法是“text/plain”,例如,这就是接收结果字符串的方式。
0
jeandenis dot boivin at gmail dot com
17 年前
$domTranObj = $xslProcessor->transformToDoc($domXmlObj);
$domHtmlText = $domTranObj->saveHTML();

请修复 <meta> 以使其成为有效的 XHTML,但不要正确地结束空节点,例如 <br />,它的输出是这样的:<br></br>。

一些浏览器将这视为 2 个不同的 <br />...

要解决此问题,请使用

$domTranObj = $xslProcessor->transformToDoc($domXmlObj);
$domHtmlText = $domTranObj->saveXML();
-1
smubldg4 at hotmail dot com
16 年前
如何解决:*致命错误:调用未定义的方法 domdocument::load()*

如果您遇到此错误,请访问 php.ini 文件并尝试注释掉以下内容,如下所示

;[PHP_DOMXML]
;extension=php_domxml.dll

突然,上面这个简单的示例按预期工作了。
-2
Thomas Praxl
17 年前
我注意到 libxslt (php4) 和通过 XSLTProcessor 进行的转换之间存在不兼容性。
Php5 和 XSLTProcessor 似乎添加了隐式的 CDATA 节点元素。
如果您有一个像这样的 xslt

<script type="text/javascript">
foo('<xsl:value-of select="bar" />');
</script>

它将生成

<script type="text/javascript"><![CDATA[
foo('xpath-result-of-bar');
]]></script>

(至少对于 output method="xml" 来说,为了使用 xslt1 生成严格的 xhtml)

这会导致(至少)在 Firefox 1.5 中出现错误,因为它不是有效的 javascript。
它应该看起来像这样

<script type="text/javascript">//<![CDATA[
foo('xpath-result-of-bar');
]]></script>

由于 CDATA 节点是隐式的,我无法禁用输出或在它前面放置 '//'。

我尝试了有关 xsl:text disable-output-escaping="yes" 的一切

我还尝试使用 <output cdata-section-elements="" /> 禁用隐式添加 CDATA
(我认为这将排除 script 标签。它没有)。

解决方案

<xsl:text disable-output-escaping="yes">&lt;script type="text/javascript"&gt;
foo('</xsl:text><xsl:value-of select="bar" /><xsl:text disable-output-escaping="yes">');
&lt;/script&gt;</xsl:text>

很简单,但花了我一段时间。
-2
jlipps at mac
19 年前
transformToXML,如果您之前注册了 PHP 函数,它确实会尝试在找到 php:function() 伪 XSL 函数时执行这些函数。 它甚至会找到类中的静态函数,例如

<xsl:value-of select="php:function('MyClass::MyFunction', string(@attr), string(.))" disable-output-escaping="yes"/>

但是,在这种情况下,transformToXML 不会尝试执行“MyClass::MyFunction()”。 相反,它执行“myclass:myfunction()”。 在 PHP 中,由于类和函数(我认为)是不区分大小写的,因此这不会造成问题。

当您将这些功能与 __autoload() 功能结合使用时,会出现问题。 所以,假设我有 MyClass.php,其中包含 MyFunction 定义。 通常,如果我调用 MyClass::MyFunction,PHP 会将“MyClass”传递给 __autoload(),__autoload() 将打开“MyClass.php”。

但是,我们刚刚看到,这意味着 transformToXML 会将“myclass”传递给 __autoload(),而不是“MyClass”,结果是 PHP 会尝试打开“myclass.php”,而该文件不存在,而不是打开“MyClass.php”,而该文件存在。 在不区分大小写的操作系统上,这并不重要,但在我的 RedHat 服务器上,它会很关键——PHP 会给出文件未找到错误。

我发现的唯一解决方案是编辑 __autoload() 函数以查找 XSL 文件中使用的类名,并手动将其更改为正确的案例。

当然,另一个解决方案是使用全小写类名和文件名。
To Top