Handlers are not required to be just functions. You can also use object methods to handle events. Two ways exist to register object methods as handlers, and each requires an already instantiated object. When every handler is a method of the same object, you can use the func- tion xml_set_object(), with the rest of the functionality covered up to now being unchanged.
You can also register specific methods from an object directly using handler registration func- tions. This allows multiple objects to be used for different events.
Using xml_set_object()
Other than defining the class, writing the handlers as methods of the class, and registering an instantiated object of this class with the parser, using this API is no different from what you have seen so far. The xml_set_object()function takes the parser and the instantiated object to be used for handling events as parameters. Handlers are registered in the same way. Only
the name of the function, in this case the method, is set with the handler. Parsing then is per- formed in a normal fashion, except now the object methods will be called. For example:
<?php class cXML {
public $eCount = 0;
public $cCount = 0;
function startElement($parser, $data, $attrs) { print "Tag Name: $data\n";
$this->eCount++;
}
function endElement($parser, $data) { } function characterData($parser, $data) {
print "DATA: $data END_DATA\n";
$this->cCount++;
} }
$xmldata = "<root:a><e1 att1='1'>text</e1></root>";
$xml_parser = xml_parser_create();
/* Create and register Object */
$objXML = new cXML();
xml_set_object($xml_parser, $objXML);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
xml_parse($xml_parser, $xmldata, true);
print "\nNumber of Elements: ".$objXML->eCount."\n";
print "Number of Times Character Data Handler Called: ".$objXML->cCount;
?>
Tag Name: ROOT Tag Name: E1 DATA: text END_DATA Number of Elements: 2
Number of Times Character Data Handler Called: 1
The code looks only a little different from what you have seen already. The only changes are a class definition and two lines of code that instantiate the object and register it with the parser.
Using Handler Registration
It is not always desirable to have all the handlers belonging to a single object or even to objects from the same class. The handlerparameter for the registration functions not only accepts a string identifying the function, or as in the previous section a method call, but also accepts an array containing an object and a method to use as the handler from the object.
The following example will use the same class definition and XML document from the previous example. This time, however, two objects will be instantiated, each handling the pro- cessing of different portions of the document.
$xml_parser = xml_parser_create();
$objXMLElement = new cXML();
$objXMLChar = new cXML();
xml_set_element_handler($xml_parser, array($objXMLElement, "startElement"), array($objXMLElement, "endElement"));
xml_set_character_data_handler($xml_parser, array($objXMLChar, "characterData"));
/*******
When uncommenting this block, make sure the previous line of code is commented out xml_set_character_data_handler($xml_parser, "characterData");
xml_set_object($xml_parser, $objXMLChar);
*******/
xml_parse($xml_parser, $xmldata, true);
print "\n--- objXMLElement ---\n";
print "\nNumber of Elements: ".$objXMLElement->eCount."\n";
print "Number of Times Character Data Handler Called: ".$objXMLElement->cCount."\n";
print "\n--- objXMLChar ---\n";
print "Number of Elements: ".$objXMLChar->eCount."\n";
print "Number of Times Character Data Handler Called: ".$objXMLChar->cCount;
If you look closely at this code, two objects, $objXMLElementand $objXMLChar, are instanti- ated from the xCMLclass. The element handlers are registered using arrays containing the
$objXMLElementobject and its startElement()and endElement()methods. The character data handler, on the other hand, is registered with the array containing the $objXMLCharobject and its characterData()method. When executed, the results show that the $objXMLElementobject had its startElement()method called twice while the $objXMLCharobject had its
characterData()method called once.
Tag Name: ROOT Tag Name: E1 DATA: text END_DATA --- objXMLElement --- Number of Elements: 2
Number of Times Character Data Handler Called: 0
--- objXMLChar --- Number of Elements: 0
Number of Times Character Data Handler Called: 1
The block of code commented out, at least in this case, results in the same output if it were used rather than the line above it that registered the character data handler. When the xml_set_object()method is used, any method not specifically registered with an associated object will default to the object registered with xml_set_object(). As you might have guessed, you have a lot of possibilities when using objects and the xml extension. For instance, the
“Seeing Some Examples in Action” section demonstrates a combination of building a DOM document and using the xml extension and the DOM classes.