Xsl xml with php

Заметки web-разработчика

Extensible Stylesheet Language /Transformations.
Стилевая технология, предназначенная для трансформации XML-документов в другие форматы.
Таблицы стилей XSL создаются по правилам XML-документов
Таблицы стилей XSL состоят из набора шаблонов.

// Загрузка исходного XML-документа
$xml = new DomDocument();
$xml->load(«catalog.xml»);
// Загрузка таблицы стилей XSL
$xsl = new DomDocument();
$xsl->load(«catalog.xsl»);
// Создание XSLT процессора
$processor = new XSLTProcessor();
// Загрузка XSL в процессор
$processor->importStylesheet($xsl);
// Выполнение преобразования
echo $processor->transformToXML($xml);

ПРИМЕР.
catalog.xml

h1 padding: 10px;
text-align: center;
background-color: #ccf
>

table margin: 10px;
border-collapse: collapse
>

td border: 1px solid gray;
padding: 5px
>

thead td text-align: center;
background-color: #ccf;
font-weight: bold
>

Наши книги

Наименование Автор Год издания Цена


Шаблон отрисовки книги стоимостью менее 200 руб.
—>


Шаблон отрисовки книги стоимостью более 200 руб.
—>


Шаблон отрисовки дочерних элементов книги
—>




Объединим два файла.
xslt.php
// Создание объекта XML
$xml = new DomDocument();

// Загрузка XML документа
$xml->load(«catalog.xml»);

// Создание объекта XSL
$xsl = new DomDocument();

// Загрузка XSL документа
$xsl->load(«catalog.xsl»);

// Создание XSLT парсера
$processor = new XSLTProcessor();

// Загрузка XSL объекта
$processor->importStylesheet($xsl);

// Преобразование
echo $processor->transformToXML($xml);
?>

Источник

Xsl xml with php

In response to appletalk at gmail dot com

As many of you may have noticed, DOM parser gives errors if the ‘ ‘ entity is present. The E_WARN message looks like:
Warning: DOMDocument::load() [function.load]: Entity ‘nbsp’ not defined in .
There’re many ways to solve this:
.
b) Defining  
At the top of the document, after the definition, add:

]>
.
Just wanted to let people know that option b does NOT work. I’m not sure why this isn’t implemented correctly, but it isn’t, so don’t waste your time. It’s unfortunate the DOMXSL transform is so much less capable than the old xslt function.

If you’re want to use XML from a variable e.g. $xmldata but the XSLT-StyleSheet from a file, you can do it also the following way:

$xslt = new xsltProcessor ;
$xslt -> importStyleSheet ( DomDocument :: load ( ‘filename.xsl’ ));
print $xslt -> transformToXML ( DomDocument :: loadXML ( $xmldata ));
?>

If you want to use the document()-function inside your XSL stylesheet, please note that you have to use an absolute path there.
Important for windows users: the absolute path *has* to be with forward slashes, so subsitute windows-path-backslashes to forward slashes before you transform the document.

This is more usefull, no files needed, it just takes XML and XSL strings as input parameters and returns transformed XML

/**
* @param $xml
* @param $xsl
* @return string xml
*/
function transform ( $xml , $xsl ) <
$xslt = new XSLTProcessor ();
$xslt -> importStylesheet (new SimpleXMLElement ( $xsl ));
return $xslt -> transformToXml (new SimpleXMLElement ( $xml ));
>
?>

You can set an HTTP proxy for the XSLT document() function to use (as well as DTD external references) by setting http_proxy in the environment.

E.g., in Apache configuration;

I couldn’t find a way to call the function and have it really print the result without creating a variable, but well, it’s just for debugging.

Here are a couple useful tips for those who care about cross-browser compatibility.

XSLT will automatically condense it to:

While this is good, Internet Explorer breaks on empty script tags. So, the simple solution is to add something to prevent an empty tag. For example:

Also, here is a way to use IE’s conditional comments:

This will let you isolate IE-related CSS without needing to use ugly CSS hacks.

Each tag will generate a PHP error (level Warning). If you want to collect and pretty-print them, you could use a custom error handling function that collects the warnings in a static variable.

Enable libxslt library, PHP 5, under windows:

To Enable:
In your php.ini
1. Uncomment ;extension=php_xsl.dll
2. Change extension_dir to
extension_dir = «./ext»

To Confirm:
1. In a test.php page:

2. Run test.php
3. Search for «libxslt Version». It should return a version number in a XSL headed table.

Further info Google
«Configuring and Testing PHP Servers for XSL Support»

In response to how to use entities from DTD (internal or external) in XSLT. It works if you do this way:

$xsl = new DOMDocument;
$xsl->resolveExternals = TRUE;
$xsl->substituteEntities = TRUE;
$xsl->load(. );

As many of you may have noticed, DOM parser gives errors if the ‘ ‘ entity is present. The E_WARN message looks like:

Warning: DOMDocument::load() [function.load]: Entity ‘nbsp’ not defined in .

c) External Doctype
Just in case you want need other HTML entities, you can call an external doctype with the proper definitions

Of course, you can download the file and place it in your server.

Wow, I spent the better part of a day looking for how one could pass an entire test expression to an XSL stylesheet. It seems that the XSLT 1.0 specification doesn’t support it but PHP 5 (and maybe 4s) inclusion of EXSLT allows one to do exactly that.

to the element and when using an expression stored in a element write

and viola! you can now use expressions generated externally in your stylesheet!

EXSLT adds many useful functions that can be integrated into your XSL in a similar fashion. You can go to http://exslt.org/ to learn more.

If you get the following warning message:

xsltApplyOneTemplate: _if_ was not compiled in (if can for example be apply-template or some other method), i’ve found that the problem seems to be an   directly before the or what ever is causing the problem.

One way to get thru the problem is to use span tags around   like :  

Here is a simplest way to transform the xml from php

# LOAD XML FILE
$XML = new DOMDocument ();
$XML -> loadXML ( $sXml );

# START XSLT
$xslt = new XSLTProcessor ();
$XSL = new DOMDocument ();
$XSL -> load ( ‘xsl/index.xsl’ , LIBXML_NOCDATA );
$xslt -> importStylesheet ( $XSL );
#PRINT
print $xslt -> transformToXML ( $XML );
?>

The following code is a wrapper to support calls to some of the old xslt_* functions:

if (PHP_VERSION >= 5) // Emulate the old xslt library functions
function xslt_create() return new XsltProcessor();
>

function xslt_process($xsltproc,
$xml_arg,
$xsl_arg,
$xslcontainer = null,
$args = null,
$params = null) // Start with preparing the arguments
$xml_arg = str_replace(‘arg:’, », $xml_arg);
$xsl_arg = str_replace(‘arg:’, », $xsl_arg);

// Create instances of the DomDocument class
$xml = new DomDocument;
$xsl = new DomDocument;

// Load the xml document and the xsl template
$xml->loadXML($args[$xml_arg]);
$xsl->loadXML($args[$xsl_arg]);

// Load the xsl template
$xsltproc->importStyleSheet($xsl);

// Set parameters when defined
if ($params) foreach ($params as $param => $value) $xsltproc->setParameter(«», $param, $value);
>
>

// Start the transformation
$processed = $xsltproc->transformToXML($xml);

// Put the result in a file when specified
if ($xslcontainer) return @file_put_contents($xslcontainer, $processed);
> else return $processed;
>

function xslt_free($xsltproc) unset($xsltproc);
>
>

$arguments = array(
‘/_xml’ => file_get_contents(«newxslt.xml»),
‘/_xsl’ => file_get_contents(«newxslt.xslt»)
);

$xsltproc = xslt_create();
$html = xslt_process(
$xsltproc,
‘arg:/_xml’,
‘arg:/_xsl’,
null,
$arguments
);

Calling the Saxon XSLT Processor is a very esay task to do!

You just need to do some simple task

1. Install the JavaBridge for PHP

2. Download the freeware (B) Saxon distribution from http://saxon.sourceforge.net/

3. Put the jar files in a directory whre you have access

4. Use this sample of code

// Directory where the jar files are located
define(«SAXON_DIR», $_SERVER[‘DOCUMENT_ROOT’].»/saxonb8.9.0/»);

// include the jars
java_require(SAXON_DIR.»saxon8.jar;».SAXON_DIR.»saxon8-dom.jar»);

$sXslFile = $_SERVER[‘DOCUMENT_ROOT’].»/myfirst.xsl»; // The xsl file
$sXmlFile = $_SERVER[‘DOCUMENT_ROOT’].»/myfirst.xml»; // The xml file

try
$oXslSource = new java(«javax.xml.transform.stream.StreamSource», «file://».$sXslFile);
$oXmlSource = new java(«javax.xml.transform.stream.StreamSource», «file://».$sXmlFile);

$oFeatureKeys = new JavaClass(«net.sf.saxon.FeatureKeys»);

// Create the Factory
$oTransformerFactory = new java(«net.sf.saxon.TransformerFactoryImpl»);

//Disable source document validation
$oTransformerFactory->setAttribute($oFeatureKeys->SCHEMA_VALIDATION, 4);

// Create a new Transformer
$oTransFormer = $oTransformerFactory->newTransformer($oXslSource);

// Create a StreamResult to store the output
$oResultStringWriter = new java(«java.io.StringWriter»);
$oResultStream = new java(«javax.xml.transform.stream.StreamResult», $oResultStringWriter);

// Transform
$oTransFormer->transform($oXmlSource, $oResultStream);

// Echo the output from the transformation
echo java_cast($oResultStringWriter->toString(), «string»);

>
catch(JavaException $e) echo java_cast($e->getCause()->toString(), «string»);
exit;
>

This is working quite well.

Источник

XSLTProcessor::transformToXml

Transforms the source node to a string applying the stylesheet given by the xsltprocessor::importStylesheet() method.

Parameters

The DOMDocument or SimpleXMLElement object to be transformed.

Return Values

The result of the transformation as a string or false on error.

Examples

Example #1 Transforming to a string

// Load the XML source
$xml = new DOMDocument ;
$xml -> load ( ‘collection.xml’ );

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

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

echo $proc -> transformToXML ( $xml );

The above example will output:

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

Fight for your mind

by Ben Harper — 1995


Electric Ladyland

by Jimi Hendrix — 1997

See Also

User Contributed Notes 11 notes

The transformToXML function can produce valid XHTML output — it honours the 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 element in your XSL stylesheet:

Entities are omitted from the output with the code above.
The symptom was that  
— 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

$xsl = new DOMDocument ;
$xsl -> substituteEntities = true ; // $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.

function hideEntities ( $data ) <
return str_replace ( «&» , «&» , $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.

// 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 ( «&» , «&» , $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
?>

Источник

Читайте также:  Neural networks in javascript
Оцените статью