WebReference.com - Part 2 of Chapter 10 from Professional PHP4 XML, from Wrox Press Ltd (4/4) | WebReference

WebReference.com - Part 2 of Chapter 10 from Professional PHP4 XML, from Wrox Press Ltd (4/4)

To page 1To page 2To page 3current page
[previous]

Professional PHP4 XML, Chapter 10: Putting It Together

Using XSLT To Modify a Document

XSLT can also be used to modify an XML document; we need to write stylesheets to perform the transformations, receiving parameters about what to do.

For example, we can write the following XSLT file to add a product to a shopping cart:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="utf-8" />
 
<xsl:param name="pid" />
<xsl:param name="name" />
<xsl:param name="desc" />  
<xsl:param name="quantity" />
<xsl:param name="unit_price" />
   
  <xsl:template match="/cart/products">
    <xsl:element name="product">
      <xsl:attribute name="pid">
        <xsl:value-of select="$pid" />
      </xsl:attribute>
      <xsl:element name="name"><xsl:value-of select="$name" /></xsl:element>
      <xsl:element name="desc"><xsl:value-of select="$desc" /></xsl:element>
      <xsl:element name="quantity">
        <xsl:value-of select="$quantity"/>
      </xsl:element>
      <xsl:element name="unit_price">
        <xsl:value-of select="$unit_price"/>
      </xsl:element>
    </xsl:element>
    <xsl:apply-templates />
  </xsl:template>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

The interesting issue here is that the XSLT stylesheet receives parameters with the information of the product to be added. The parameters declared at the beginning of the stylesheet show the parameters that the stylesheet is expecting to receive.

This PHP file shows how to pass parameters to an XSLT stylesheet using Sablotron:

// Allocate a new XSLT processor
$xh = xslt_create();
$new_prod = Array("pid" => "19",
                  "name" => "Newby",
                  "desc" => "A new product",
                  "quantity" => "1",
                  "unit_price" => "19"
            );
$result = xslt_process($xh, 'cart.xml', 
                       'addProduct.xsl', NULL, Array(), $new_prod);
if ($result) {
    print ($result);
} else {
    print ("Sorry, cart.xml could not be transformed by ");
    print ("addProduct.xsl into the \$result variable. ");
    print ("The reason is that " . xslt_error($xh));  
    print (" and the error code is " . xslt_errno($xh));
}
xslt_free($xh);

We are not using an XSLT abstraction class here to show how to pass parameters to Sablotron.

And the following XSLT stylesheet removes products from the cart:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="utf-8" />
<xsl:param name="pid" />
  <xsl:template match="/cart/products/product[@pid=$pid]">
  </xsl:template>
  
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

This is a simple stylesheet where, if the product with the ID passed as a parameter is found, then nothing is sent and everything else is copied.

This PHP code tests the stylesheet:

// Allocate a new XSLT processor
$xh = xslt_create();
$new_prod = Array("pid" => "13");
$result = xslt_process($xh, 'cart.xml', 
                       'removeProduct.xsl', NULL, Array(), $new_prod);
if ($result) {
    print $result;
} else {
    print ("Sorry, cart.xml could not be transformed by ");
    print ("removeProduct.xsl into the \$result variable. ");
    print ("The reason is that " . xslt_error($xh));  
    print (" and the error code is " . xslt_errno($xh));
}
xslt_free($xh);

If the DOM approach is too slow or uses a lot of resources, or we find it hard to write SAX filters for some modifications, it is good to use an XSLT stylesheet.

The main advantage of using XSLT is that powerful and complex modifications can be performed. However, it uses more resources than SAX, and passing parameters is not so easy if we have to perform complex transformations. One more problem with XSLT is that it does not have a caching option as yet.

Abstracting the Modifications To an XML Document

As with transformations, we may implement modifications to an XML document in many different ways - using XSLT, SAX filters, or the DOM approach as per the circumstances. Then it's logical to think that abstracting the modifications can be a good idea. We have several ways to abstract transformations to an XML document - the command pattern of OOP can be used to implement a command processor that can perform/undo commands from an XML document.

We can find a good description of the command pattern in this article from http://www.xml.com/pub/a/2000/01/19/feature/index.html.


To page 1To page 2To page 3current page
[previous]

Created: August 19, 2002
Revised: August 19, 2002

URL: http://webreference.com/programming/php/php4xml/chap10/2/4.html