WebReference.com - Part 3 of Chapter 10 from Professional PHP4 XML, from Wrox Press Ltd (2/7)
[previous] [next] |
Professional PHP4 XML, Chapter 10: Putting It Together
Using SAX To Create PHP Objects from XML
Here we build a SAX filter that can be used to create the book
objects from our document. We store references to the objects in an array to keep track of the objects in memory. This is the strategy used to create objects:
|
class FilterBuildBooks extends AbstractFilter
{
var $oneBook = 0;
var $book;
var $property = 0;
var $books = Array();
function GetBooks()
{
return $this->books;
}
function StartElementHandler($name, $attribs)
{
if ($name == "book") {
$this->books[] = new Book();
$this->oneBook = 1;
} else {
if ($this->oneBook) {
$this->property = $name;
}
}
$this->listener->StartElementHandler($name, $attribs);
}
function EndElementHandler($name)
{
$this->property = 0;
if ($name == "book") {
$this->oneBook = 0;
}
$this->listener->EndElementHandler($name);
}
function CharacterDataHandler($data)
{
if ($this->oneBook && $this->property) {
// Here we construct the name of the method to be called.
$method_get = "get".strtoupper(substr($this->property, 0, 1)) .
substr($this->property, 1);
$method_set = "set".strtoupper(substr($this->property, 0, 1)) .
substr($this->property, 1);
$prop = $this->books[count($this->books)-1]->$method_get();
$this->books[count($this->books)-1]->$method_set($prop.$data);
}
$this->listener->CharacterDataHandler($data);
}
}
This PHP code parses the XML file that creates the book objects:
$f1 = new ExpatParser("books.xml");
$f1->ParserSetOption(XML_OPTION_CASE_FOLDING, 0);
$f2 = new FilterBuildBooks();
$f3 = new FilterNull();
$f2->SetListener($f3);
$f1->SetListener($f2);
$f1->Parse();
$books = $f1->listener->GetBooks();
We can make two observations about this piece of code:
A
NULL
filter was used at the end of the chain since we neither want any output nor want to store the XML. Once parsed this design is better than making theFilterBuildBooks
object aFilterNull
because with this schema we can do something with the parsed XML document besides creating the objects. All our filters should pass events to a listener and we can use aNULL
filter at the end.The books are obtained calling the
getBooks()
method of theFilterBuildBooks
object through the parser; because theFilterBuildBooks
is a member (listener) of the parser. If we try to obtain the books using$f2->getBooks()
we will get an empty array.
The Flyweight Pattern
There's an interesting application of the Flyweight pattern in this example. Imagine we are processing a very large XML document where we create objects from the document. Many objects created from the document may have the same content for some of their properties if the elements repeat in the XML document. For instance, in our example, we may have many books from the same author.
In such cases we can use the Flyweight pattern to use an object that resolves the properties of the book objects.
Instead of storing the value of each property, we ask a Flyweightfactory
object to return an object representing the property. We won't know if many objects share this object and the functionality of the object can be the same. The factorizing object can use a hashtable, or something similar, to store and retrieve properties reusing the same value for as many objects as it can, thus reducing the amount of memory consumed by the objects.
The flyweight pattern is an optimization pattern. It can be used when we are creating a very large number of objects and those objects may have properties with a long value that may be the same value for a big number of objects.
We can read about this pattern in the article at https://www.xml.com/pub/a/2000/01/19/feature/index.html.
[previous] [next] |
Created: August 26, 2002
Revised: August 26, 2002
URL: https://webreference.com/programming/php/php4xml/chap10/3/2.html