I'm new to the forum, trying to get some help for a class that another developer has written. I have some experience with programming myself, but not enough with OOP and passing by reference, which is why I have a problem here.
This class is written to import XML from a web service. It should return an array of nodes (Xml objects), but only returns the first 1-2 of 18 elements in the XML doc.
This is what I've discovered so far. The parse() function is where the problem is. The function should return the Xml object ($node) when an element is found.
[EDIT] I just tested removing the & in front of $n in the parse() function while loop. It returns all elements, each as a child of the next. [/EDIT]
Running PHP Version 5.2.4-2ubuntu5.5 locally to debug, but I get the same problems with 5.2.5 on my web hosting account.
Code: Select all
<?php
class Xml extends Object {
public $name = '';
public $attr = array();
public $elem = array();
public $text = array();
public $nodes = array();
public function __get_value() {
return isset($this->text[0]) ? $this->text[0] : '';
}
public function __set_value($val) {
$this->text[0] = $val;
}
public function locate($type, $id, $value) {
foreach($this->elem[$type] as $node) {
if($node->attr[$id] == $value) {
return $node;
}
}
}
public static function read($uri) {
$xml = new XMLReader();
if(!$xml->open($uri)) {
drupal_set_message("common.inc (78): Failed to open '$uri' for reading.", "error");
return false;
}
$root = Xml::parse($xml);
$xml->close();
return $root;
}
public static function parse(&$xml){
if(!$xml->read()) {
return false;
}
else if($xml->nodeType == XMLReader::END_ELEMENT) {
return false;
}
else if($xml->nodeType == XMLReader::ELEMENT) {
$node = new Xml();
$node->name = $xml->name;
if($xml->hasAttributes) {
while($xml->moveToNextAttribute()) {
$node->attr[$xml->name] = $xml->value;
}
}
if(!$xml->isEmptyElement) {
while($n = Xml::parse($xml)) {
if(isset($n->name)) {
if($n->name == '#text') {
$node->text[] = &$n->value;
}
else {
$node->elem[$n->name][] = &$n;
}
# Changed from $this->nodes[] = &$n;
# since the Xml class is called without being
# instantiated every time.
if($this)$this->nodes[] = &$n;
}
}
}
return $node;
}
else if($xml->nodeType == XMLReader::TEXT) {
$node = new stdClass();
$node->name = $xml->name;
$node->value = $xml->value;
return $node;
}
return true;
}
};
?>
Code: Select all
<CategorySearch format="List" id="601">
<Category catalogs="false" id="601" name="Home Page" refinements="false"/>
<Category catalogs="false" id="100334923" name="Baby & Nursery" refinements="false"/>
<Category catalogs="false" id="100471423" name="Entertainment" refinements="false"/>
<Category catalogs="false" id="172601" name="Cars & Accessories" refinements="false"/>
<Category catalogs="false" id="110001" name="Computers & Software" refinements="false"/>
<Category catalogs="false" id="120501" name="Electronics" refinements="false"/>
<Category catalogs="false" id="107301" name="Fashion & Lingerie" refinements="false"/>
<Category catalogs="false" id="159001" name="Finance" refinements="false"/>
<Category catalogs="false" id="169901" name="Travel" refinements="false"/>
<Category catalogs="false" id="117901" name="Games, Consoles & Toys" refinements="false"/>
<Category catalogs="false" id="100007413" name="Gifts & Gadgets" refinements="false"/>
<Category catalogs="false" id="132801" name="Health & Beauty" refinements="false"/>
<Category catalogs="false" id="134301" name="Home & Garden" refinements="false"/>
<Category catalogs="false" id="144601" name="Household Appliances" refinements="false"/>
<Category catalogs="false" id="125301" name="Mobiles, Phones & Faxes" refinements="false"/>
<Category catalogs="false" id="163601" name="Sport & Fitness" refinements="false"/>
<Category catalogs="false" id="100524123" name="Cashback" refinements="false"/>
</CategorySearch>I'm sure there's a simple solution to this, but I am not able to figure it out.
Let me know if I can provide more details for you. Your help is much appreciated!