WebReference.com - Part 1 of Chapter 10 from Professional PHP4 XML, from Wrox Press Ltd (2/7)
[previous] [next] |
Professional PHP4 XML
Using DOM for XML Transforming
It is possible to use the DOM standard to transform an XML file. We can parse the XML file into the DOM tree and then perform different operations on the tree to transform the source XML file into a different XML file. This is useful only in limited situations, where the result is also XML and the file is small and the transformation simple. Since using the DOM standard for transformation is restricted to very specific situations we shall not look into a detailed example in this chapter.
Here are some of the advantages and disadvantages of using DOM for XML transformations:
Advantages | Disadvantages |
Based on a solid standard by the W3C. | Uses a lot of resources. Not good for transforming medium- to large-sized documents. |
Easy for removing/adding elements from a document. | Makes sense if the transformation implies modifying a document, very hard if the transformation result is not XML. |
Scales badly, not suitable for online processing unless the document size is known and small. |
Using XSLT for XML Transforming
XSLT is the de facto standard for transforming XML content. This language was created to define XML transformations. We write an XSLT stylesheet and then use an XSLT processor to transform the XML file using the XSLT stylesheet, the result can be XML, HTML, a binary format, or some text.
Chapter 8 covers XSLT support in PHP.
We can easily write an XSLT stylesheet to perform our sample transformation. Here is the tr1.xsl XSLT stylesheet:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="utf-8" />
<xsl:template match="name/text()">
<b>
<xsl:value-of select='translate(string(.),
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ")' />
<xsl:apply-templates />
</b>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The source XML file is transformed using the above stylesheet and the output redirected to a new XML file. Once it is done, we can see that just the text contents of the <name>
element are matched, and the output displays the text in uppercase because of the translate()
function enclosed in a <b>
tag in the above stylesheet. We also used a 'match anything else' template to copy the rest of the XML document without modifications to the result.
The presented stylesheet is useful as a base template for changing XML documents since it copies everything that is not matched as-is to the output document.
This is the PHP code used to perform the transformation:
<?php
include_once("class_xslt.php");
$xslt = new Xslt();
$xslt->SetXml("applications.xml");
$xslt->SetXsl("tr1.xsl");
if ($xslt->Transform()) {
$ret = $xslt->GetOutput();
print ($ret);
} else {
print ("Error:".$xslt->GetError());
}
?>
And this is the class_xslt.php
abstraction that we used:
<?php
class Xslt
{
var $xsl, $xml, $output, $error ;
/* Constructor */
function Xslt()
{
$this->processor = xslt_create();
}
/* Destructor */
function Destroy()
{
xslt_free($this->processor);
}
/* output methods */
function SetOutput($string)
{
$this->output = $string;
}
function GetOutput()
{
return $this->output;
}
/* set methods */
function SetXmlString($xml)
{
$this->xml = $xml;
return true;
}
function SetXslString($xsl)
{
$this->xsl = $xsl;
return true;
}
function SetXml($uri)
{
if ($doc = new DocReader($uri)) {
$this->xml = $doc->GetString();
return true;
} else {
$this->SetError("Could not open $xml");
return false;
}
}
function SetXsl($uri)
{
if ($doc = new DocReader($uri)) {
$this->xsl = $doc->GetString();
return true;
} else {
$this->SetError("Could not open $uri");
return false;
}
}
/* transform method */
function Transform()
{
$arguments = array('/_xml' => $this->xml,
'/_xsl' => $this->xsl
);
$ret = xslt_process($this->processor, 'arg:/_xml', 'arg:/_xsl',
NULL, $arguments);
if (!$ret) {
$this->SetError(xslt_error($this->processor));
return false;
} else {
$this->SetOutput($ret);
return true;
}
}
/* Error Handling */
function SetError($string)
{
$this->error = $string;
}
function GetError()
{
return $this->error;
}
}
/* DocReader -- read a file or URL as a string */
/* test */
/*
$docUri = new DocReader('https://www.someurl.com/doc.html');
print ($docUri->GetString());
*/
class DocReader
{
var $string; // public string representation of file
var $type; // private URI type: 'file', 'url'
var $bignum = 1000000;
var $uri;
/* public constructor */
function DocReader($uri)
{ // returns integer
$this->SetUri($uri);
$this->uri = $uri;
$this->SetType();
$fp = fopen($this->GetUri(), "r");
if ($fp) { // get length
if ($this->GetType() == 'file') {
$length = filesize($this->GetUri());
} else {
$length = $this->bignum;
}
$this->SetString(fread($fp, $length));
return 1;
} else {
return 0;
}
}
/* determine if a URI is a filename or URL */
function IsFile($uri)
{ // returns boolean
if (strstr($uri, 'https://') == $uri) {
return false;
} else {
return true;
}
}
/* set and get methods */
function SetUri($string)
{
$this->uri = $string;
}
function GetUri()
{
return $this->uri;
}
function SetString($string)
{
$this->string = $string;
}
function GetString()
{
return $this->string;
}
function SetType()
{
if ($this->IsFile($this->uri)) {
$this->type = 'file';
} else {
$this->type = 'url';
}
}
function GetType()
{
return $this->type;
}
}
?>
[previous] [next] |
Created: August 12, 2002
Revised: August 12, 2002
URL: https://webreference.com/programming/php/php4xml/chap10/1/2.html