XSLTProcessor::transformToXml

(PHP 5, PHP 7, PHP 8)

XSLTProcessor::transformToXml β€” ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Π΅Ρ‚ Π² XML-строку

ОписаниС

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

ΠœΠ΅Ρ‚ΠΎΠ΄ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Ρ‹Π²Π°Π΅Ρ‚ исходный ΡƒΠ·Π΅Π» Π² строку, примСняя Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ стилСй, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ установили ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ xsltprocessor::importStylesheet().

Бписок ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²

document

ΠžΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ трСбуСтся ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ класса Dom\Document, DOMDocument, SimpleXMLElement ΠΈΠ»ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ совмСстим с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ libxml.

returnClass

Π§Π΅Ρ€Π΅Π· этот Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ класс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Π΅Ρ€Π½Ρ‘Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ XSLTProcessor::transformToDoc(). Π’ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ класса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π»ΠΈΠ±ΠΎ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚, Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ классу, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Π»ΠΈ Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ document.

Ошибки

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ PHP-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ошибки:

  • ΠœΠ΅Ρ‚ΠΎΠ΄ выбрасываСт ΠΎΡˆΠΈΠ±ΠΊΡƒ Error, Ссли Π² Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΈ Π²Ρ‹Π·Π²Π°Π»ΠΈ PHP-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°, Π½ΠΎ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ рСгистрировали, ΠΈΠ»ΠΈ Ссли callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с Ρ‚Π°ΠΊΠΈΠΌ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ Π½Π΅ зарСгистрировали.
  • ΠœΠ΅Ρ‚ΠΎΠ΄ выбрасываСт ΠΎΡˆΠΈΠ±ΠΊΡƒ TypeError, Ссли ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· XPath-выраТСния синтаксисом php:function вмСсто строкового названия ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.
  • ΠœΠ΅Ρ‚ΠΎΠ΄ выбрасываСт ΠΎΡˆΠΈΠ±ΠΊΡƒ Error, Ссли callback-функция вмСсто DOM-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния

ΠœΠ΅Ρ‚ΠΎΠ΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ прСобразования, ΠΈΠ»ΠΈ false, Ссли Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ошибка.

Бписок измСнСний

ВСрсия ОписаниС
8.4.0 ВмСсто прСдупрСТдСния ΠΌΠ΅Ρ‚ΠΎΠ΄ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ выбрасываСт ΠΎΡˆΠΈΠ±ΠΊΡƒ Error, Ссли callback-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ.
8.4.0 Π”ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² класса Dom\Document.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #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);

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

ΠŸΡ€ΠΈΠ²Π΅Ρ‚! Π”ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒ Π² Π·Π°ΠΌΠ΅Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дисков Николаса Π­Π»ΠΈΠ°ΡˆΠ΅Π²ΠΈΡ‡Π°!

<h1>Π‘ΠΎΡ€ΠΈΡ‚Π΅ΡΡŒ Π·Π° свой Ρ€Π°Π·ΡƒΠΌ (Fight for your mind)</h1><h2>Π‘Π΅Π½ Π₯Π°Ρ€ΠΏΠ΅Ρ€ (Ben Harper) - 1995</h2><hr>
<h1>ЭлСктричСская Π›Π΅Π΄ΠΈΠ»Π΅Π½Π΄ (Electric Ladyland)</h1><h2>Π”ΠΆΠΈΠΌΠΈ Π₯Сндрикс (Jimi Hendrix) - 1997</h2><hr>

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #2 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ прСобразования ΡƒΠ·Π»Π° Π² строку ΠΈΠ· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса Dom\Document

<?php

$xml
= Dom\XMLDocument::createFromFile('collection.xml');
$xsl = Dom\XMLDocument::createFromFile('collection.xsl');

// Настройка прСобразования
$proc = new XSLTProcessor();
$proc->importStyleSheet($xsl); // ΠŸΡ€ΠΈΠΊΡ€Π΅ΠΏΠ»Π΅Π½ΠΈΠ΅ XSL-ΠΏΡ€Π°Π²ΠΈΠ»

echo $proc->transformToXML($xml);

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

ΠŸΡ€ΠΈΠ²Π΅Ρ‚! Π”ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒ Π² Π·Π°ΠΌΠ΅Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дисков Николаса Π­Π»ΠΈΠ°ΡˆΠ΅Π²ΠΈΡ‡Π°!

<h1>Π‘ΠΎΡ€ΠΈΡ‚Π΅ΡΡŒ Π·Π° свой Ρ€Π°Π·ΡƒΠΌ (Fight for your mind)</h1><h2>Π‘Π΅Π½ Π₯Π°Ρ€ΠΏΠ΅Ρ€ (Ben Harper) - 1995</h2><hr>
<h1>ЭлСктричСская Π›Π΅Π΄ΠΈΠ»Π΅Π½Π΄ (Electric Ladyland)</h1><h2>Π”ΠΆΠΈΠΌΠΈ Π₯Сндрикс (Jimi Hendrix) - 1997</h2><hr>

Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅

οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 11 notes

up
6
werner@mollentze ΒΆ
19 years ago
The transformToXML function can produce valid XHTML output - it honours the <xsl:output> element's attributes, which defines the format of the output document.

For instance, if you want valid XHTML 1.0 Strict output, you can provide the following attribute values for the <xsl:output> element in your XSL stylesheet:

<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" />
up
5
lsoethout at hotmail dot com ΒΆ
20 years ago
The function transformToXML has a problem with the meta content type tag. It outputs it like this:

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

which is not correct X(HT)ML, because it closes with '>' instead of with '/>'.

A way to get the output correct is to use instead of transformToXML first transformToDoc anf then saveHTML:

    $domTranObj = $xslProcessor->transformToDoc($domXmlObj);
    $domHtmlText = $domTranObj->saveHTML();
up
7
Charlie Murder ΒΆ
16 years ago
To prevent your xsl file from automatically prepending 

<?xml version="1.0"?> 

whilst keeping the output as xml, which is preferable for a validated strict xhtml file, rather specify output as 

<xsl:output method="xml" omit-xml-declaration="yes" />
up
3
michael dot weibel at tilllate dot com ΒΆ
16 years ago
If you retrieve "false" from the transformToXML method, use libxml_get_last_error() or libxml_get_errors() to retrieve the errors.
up
3
john ΒΆ
18 years ago
If your xsl doesn't have <html> tags. The output will contain <?xml version="1.0"?>. To fix this you can add the following to your xsl stylesheet:

<xsl:output
method="html" />
up
6
zweibieren at yahoo dot com ΒΆ
15 years ago
Entities are omitted from the output with the code above.  
The symptom was that &nbsp; 
-- which should work with UTF-8 encoding -- 
did not even get to XSLTProcessor, let alone through it.
After too much hacking I discovered the simple fix:
set substituteEntities to true in the DOMDocument for the XSL file.
That is, replace the loading of the xsl document with

<?php
   $xsl = new DOMDocument;
   $xsl->substituteEntities = true;    // <===added line
   $xsl->load('collection.xsl');
?>

However, this fails when data entries have HTML entity references. (Some database entries may even contain user generated text.) libxml has the pedantic habit of throwing a FATAL error for any undefined entitiy. Solution: hide the entities so libxml doesn't see them.

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

You could just add this to the example, but it is tidier to define a function to load data into a DOMDocument. This way you don't need entity declarations in catalog.xsl, either.

<?php
// Added function for  Example #1  

/** Load an XML file and create a DOMDocument.
Handles arbitrary entities, even undefined ones.
*/
function fileToDOMDoc($filename) {
    $dom= new DOMDocument;
    $xmldata = file_get_contents($filename);
    $xmldata = str_replace("&", "&amp;", $xmldata);  // disguise &s going IN to loadXML()
    $dom->substituteEntities = true;  // collapse &s going OUT to transformToXML()
    $dom->loadXML($xmldata);
    return $dom;
}

// Compare with  Example #1 Transforming to a string

// Load the XML sources
$xml = fileToDOMDoc('collection.xml');
$xsl = fileToDOMDoc('collection.xsl');

// Configure the transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); 

// transform $xml according to the stylesheet $xsl
echo $proc->transformToXML($xml); // transform the data
?>
up
3
Josef Hornych ΒΆ
11 years ago
Note that the method's name is sort of deceiving, because it does not only output XML, but any string that is generated by the processor. It should rather be called transformToString. So if your output method is  "text/plain", for example, this is the way to receive the resulting string.
up
0
jeandenis dot boivin at gmail dot com ΒΆ
19 years ago
$domTranObj = $xslProcessor->transformToDoc($domXmlObj);
$domHtmlText = $domTranObj->saveHTML();

Do fix the <meta> for valid XHTML but do not correctly end empty node like <br /> which ouput like this : <br></br>

Some browser note this as 2 different <br /> ...

To fix this use 

$domTranObj = $xslProcessor->transformToDoc($domXmlObj);
$domHtmlText = $domTranObj->saveXML();
up
-1
smubldg4 at hotmail dot com ΒΆ
18 years ago
How to fix:: *Fatal error: Call to undefined method domdocument::load()*

If you get this error, visit the php.ini file and try commenting out the following, like this:

;[PHP_DOMXML]
;extension=php_domxml.dll

Suddenly, the wonderfully simple example above works as advertised.
up
-2
Thomas Praxl ΒΆ
19 years ago
I noticed an incompatibility between libxslt (php4) and the transformation through XSLTProcessor.
Php5 and the XSLTProcessor seem to add implicit CDATA-Section-Elements.
If you have an xslt like 

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

It will result in

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

(at least for output method="xml" in order to produce strict xhtml with xslt1)

That brings up an error (at least) in Firefox 1.5 as it is no valid javascript.
It should look like that:

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

As the CDATA-Section is implicit, I was not able to disable the output or to put a '//' before it.

I tried everything about xsl:text disable-output-escaping="yes" 

I also tried to disable implicit adding of CDATA with <output cdata-section-elements="" />
(I thought that would exclude script-tags. It didn't).

The solution:

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

Simple, but it took me a while.
up
-2
jlipps at mac ΒΆ
21 years ago
transformToXML, if you have registered PHP functions previously, does indeed attempt to execute these functions when it finds them in a php:function() pseudo-XSL function. It even finds static functions within classes, for instance:

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

However, in this situation transformToXML does not try to execute "MyClass::MyFunction()". Instead, it executes "myclass:myfunction()". In PHP, since classes and functions are (I think) case-insensitive, this causes no problems.

A problem arises when you are combining these features with the __autoload() feature. So, say I have MyClass.php which contains the MyFunction definition. Generally, if I call MyClass::MyFunction, PHP will pass "MyClass" to __autoload(), and __autoload() will open up "MyClass.php".

What we have just seen, however, means that transformToXML will pass "myclass" to __autoload(), not "MyClass", with the consequence that PHP will try to open "myclass.php", which doesn't exist, instead of "MyClass.php", which does. On case-insensitive operating systems, this is not significant, but on my RedHat server, it is--PHP will give a file not found error.

The only solution I have found is to edit the __autoload() function to look for class names which are used in my XSL files, and manually change them to the correct casing.

Another solution, obviously, is to use all-lowercase class and file names.