XML/Class Problem
| From: | Sebastian dot Will at sercon dot de | Date: | Thu, 24 Aug 2000 14:15:19 +0000 |
| Subject: | XML/Class Problem | ||
| Groups: | php.general | ||
| Request: | Send a blank email to php-general+get-13389@lists.php.net to get a copy of this message | ||
Hi everybody,
I wanted to wrap the XML parsing functions into a easy to use class that
translates any XML document into a tree in the memory. It worked when I
didn't write it in a class in the beginning, but now, I'm stuck. I think,
there is a problem regarding the xml_set_[fo]_handler lines: If I wrote,
e.g.
xml_set_element_handler($this->xml_parser, "startElement", "endElement");
php doesn't find any of these methods outside of the class (sure), but if I
want to reference the class-internal methods, they are not called (see
'echo "huhu"' in startElement()). I post the whole source here, please
forgive the lengthy document, but I think, the context matters here. I'm
not that experienced in php, it's possible that I just missed some php
specific details.
Thanks for your time (and bandwidth :))
Sebastian
------------------------------ snip 8>< ------------------------------
<?php
# This script formats a xml file according to some rules. These rules
# are processed in the function that xml_set_character_data_handler
# defines. We have to remember, in which element we are, and furthermore,
# which ancestor elements the current element has.
class Node {
var $name;
var $attributes;
var $ancestors = "/";
var $data;
function Node($tree, $attribs) {
$this->name = array_pop($tree);
$this->ancestors .= implode("/", $tree);
$this->attributes = $attribs;
printf("%s, %s, %s", $this->name, $this->ancestors,
$this->attributes);
}
function add_data($value) {
$this->data .= ' '.$value;
}
function print_name() {
return "$name";
}
function is_child($node) {
$result = preg_match("/^$ancestors/", $node->ancestors, $match);
if ($node->ancestors == $this->ancestors) $result = false;
return $result;
}
}
class XML {
var $file;
var $tree = array();
var $attributes = array();
var $nodes = array();
var $xml_parser;
var $xsl_file;
function XML($file) {
# Setting up the parser
$this->xml_parser = xml_parser_create();
xml_set_element_handler($this->xml_parser, "$this->startElement",
"$this->endElement");
xml_set_character_data_handler($this->xml_parser,
"$this->characterData");
xml_set_processing_instruction_handler ($this->xml_parser,
"$this->process_instruction");
xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING,
false);
$this->file = $file;
}
function set_parser_option($option, $value) {
xml_parser_set_option($this->xml_parser, $option, $value);
}
function parse() {
if (!($fp = @fopen($this->file, "r"))) {
die(print("Couldn't open file: $this->file\n"));
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($this->xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d\n",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
}
function startElement($parser, $name, $attribs) {
echo "huhu";
# Adding the additional element to the tree, including attributes
$this->tree[] = $name;
$this->attributes[] = $attribs;
$this->nodes[] = new Node($this->tree, attribs);
}
function endElement($parser, $name) {
# Remove the element from the tree, including the attributes
array_pop($this->tree);
array_pop($this->attributes);
}
function characterData($parser, $data) {
$data = ltrim($data);
if ($data != "") $this->nodes[count($nodes)-1]->add_data($data);
}
function process_instruction($parser, $target, $data) {
if (preg_match("/xml:stylesheet/", $target, $match) && preg_match
("/type=\"text\/xsl\"/", $data, $match)) {
preg_match("/href=\"(.+)\"/i", $data, $xsl_file);
$this->xsl_file = $xls_file[1];
}
}
function print_nodes() {
# Printing the nodes in a formatted way
for ($i = 0; $i < count($this->nodes); $i++) {
printf ("<p><b>%s</b><br>\n",
$this->nodes[$i]->name);
printf ("Ancestors: %s<br>\n", $this->nodes[$i]->ancestors);
if (count($this->nodes[$i]->attributes) > 1) {
print "Attributes: ";
while (list($k, $v) = each($this->nodes[$i]
->attributes)) {
print "$k = $v, ";
}
print "<br>";
}
if ($this->nodes[$i]->data != "") {
printf ("Data: %s\n", $this->nodes[$i]->data);
}
print "</p>\n";
}
printf("We have <b>%d nodes</b> in our XML doc.<br>\n", count
($this->nodes));
printf("Is <i>%s</i> a child of <i>%s</i>? ",
$this->nodes[11]
->name, $this->nodes[8]->name);
if ($this->nodes[8]->is_child($this->nodes[11])) print
"<b>yes</b>"; else print "<b>no</b>"; print
"<br>\n";
}
}
$xml = new XML("artikel.xml");
$xml->parse();
$xml->print_nodes();
?>
------------------------------ snip 8>< ------------------------------