Link to home
Start Free TrialLog in
Avatar of Impylapa
ImpylapaFlag for United Kingdom of Great Britain and Northern Ireland

asked on

transferring php xml parsing code into a class

I have to transfer a php parser script into a class.  The original script works alright, but when I transfer it into a class I do not get the parsed data out to display.  Being a beginner in scripting, I am somewhat lost, have been trying to find a solution for days and nights, also with reading other code and answers, but understand too little to find what I am doing wrong.  

When I run the first set of code pasted below, the data displays alright.  However, when I try to oursource the code into a class I am unable to retrieve it from the $art = array(); variable.  At least for now I don't get any error messages anymore, but am still not further.  With the print_r checks in the artikelliste.inc.php file I can see the parsed text, but the $art array() shows as being empty.

I do hope that someone can help me with this, as I do not get further without understanding  the principle of it.  


/*xml sample file */
 
<?xml version="1.0" encoding="utf-8"?>
<artikeldaten>
	<artikel nummer="5005">
		<name>Der Herr der Ringe</name>
		<preis>39.90</preis>
	</artikel>
	<artikel nummer="6006">
		<name>Der kleine Hobbit</name>
		<preis>19.90</preis>
	</artikel>
	<artikel nummer="3003">
		<name>Grimms Maerchen</name>
		<preis>25.90</preis>
	</artikel>
	<artikel nummer="4004">
		<name>Elric von Melnibonee</name>
		<preis>29.90</preis>
	</artikel>
</artikeldaten>
 
/* the following version without a parser class displays the data alright*/
 
/* Artikel.class.php code */
 
<?php
	class Artikel {
		var $name;
		var $anzahl;
		var $preis;
		
		function Artikel($name, $preis) {
			$this->name = $name;
			$this->anzahl = 1;
			$this->preis = $preis;
		}
	}
?>
 
/* artikelliste.inc.php code = Parser*/
 
<?php
	include_once 'classes/Artikel.class.php';
	$art = array();
	
	$xmlFile = implode("", file("./xml/artikeldaten.xml"));
		
	$parser = xml_parser_create();
	xml_set_element_handler($parser, "startElement", "endElement");
	xml_set_character_data_handler($parser, "cdata");
	xml_parse($parser, $xmlFile);
	xml_parser_free($parser);
	
	/*Funktionsdeklaration*/
	
	function startElement($parser, $name, $atts) {
		global $nummer, $aktuell;
		$aktuell = $name;
		if($name == "ARTIKEL") {
			$nummer = $atts["NUMMER"];
		}
	}
	function endElement($parser, $name) {
		global $aktuell, $art, $nummer, $titel, $preis;
		if($name == "ARTIKEL") {
			$art[$nummer] = new Artikel($titel, $preis);
		}
		$aktuell = "";
	}
	function cdata($parser, $text) {
		global $aktuell, $titel, $preis;
		if($aktuell == "PREIS") $preis=$text;
		if ($aktuell == "NAME") $titel=$text;
	}
?>
 
/* artikel.php  HTML output of the data */
 
<?php
	/*require_once('includes/functions.inc.php');*/
	include 'includes/artikelliste.inc.php';
	include 'includes/style.php';  //ausgelagerter link zu CSS stylesheet.
?>
<html>
	<?php 
		echo $style_css; //variable in style.php
		//echo schreibeKorb();
	?>
	<body>
		<div id="container">
        	<div id='header'>
                <h2>Folgende B&uuml;cher k&ouml;nnen Sie bestellen</h2>
                <div id='navTop'>
                	<ul>
                    	<li><a href="warenkorb.php">Zum Warenkorb</a></li>
                        <li><a href="admin.php">Datenverwaltung</a></li>
                    </ul>
                </div>            
            </div>
            <div id='main'>
		<?php
		foreach($art as $nummer=>$art_objekt) {
                        print "<a href='warenkorb.php?artikel=$nummer'>";
                        print $art_objekt->name;
                        print "</a> ".$art_objekt->preis." Euro<p>\n";
                  }
                ?>
            </div>
	</div>
	</body>
</html>
 
/*Now I changed the code to the following, which does not work anymore.  I do not know how I get the parsed data into an array, which supposedly is needed to pass it on to the foreach function.  Please see below what I have done so far:*/
 
/* Artikelparser.class.php */
 
<?php
	include_once'Artikel.class.php';
		
	class Artikelparser {
		var $parser;
		var $art;
		var $datei;
		//var $aktuell;
		//var $nummer;
		
		function aParser($datei) {
			$this->art = array();
			$this->datei = implode("", file("./xml/artikeldaten.xml"));
			$this->parser = xml_parser_create();
			xml_set_object($this->parser, $this);
			xml_set_element_handler($this->parser, "startElement", "endElement");
			xml_set_character_data_handler($this->parser, "cdata");
			xml_parse($this->parser, $datei);
			xml_parser_free($this->parser);
		}
			function startElement($parser, $name, $atts){
				$this->aktuell = $name;
				if($this->name == "ARTIKEL") {
					$this->nummer = $atts["NUMMER"];
				}
			}
			function endElement($parser, $name){
				if($this->name == "ARTIKEL") {
					$this->art[$nummer] = new Artikel($titel, $preis);
				}
					$this->aktuell = "";
			}
		function cdata($parser, $text){
			if($this->aktuell == "PREIS") $preis=$text;
			if($this->aktuell == "NAME") $titel=$text;
		}
		function getArtikelArray() {
			return $this->art;
		}
	}
?>
/* the changed artikelliste.inc.php code */
 
<?php
	include_once 'classes/Artikelparser.class.php';
	$datei = "./xml/artikeldaten.xml";
	$a_parser = new Artikelparser($datei);
	$parsing = $a_parser->aParser($datei);
	print_r($a_parser);
	$art = $a_parser->getArtikelArray();
	print_r($art);
?>
 
/* the code of artikel.php is unchanged */

Open in new window

Avatar of Roger Baklund
Roger Baklund
Flag of Norway image

In the working code, you use global variables to store the properties $preis and $titel. This is removed in the class version.

In line 151-152, use $this-> to store the variables in the object instance:

                        if($this->aktuell == "PREIS") $this->preis=$text;
                        if($this->aktuell == "NAME") $this->titel=$text;

Do the same in line 146, also for $nummer:

                                        $this->art[$this->nummer] = new Artikel($this->titel, $this->preis);
Avatar of Impylapa

ASKER

Thank you cxr,

I will give it a try and get back as soon as I know.

Hello again

I tried it now, but unfortunately, I still do have the same problem.

The print_r checks in artikelliste.inc.php display:

Artikelparser Object ( [parser] => Resource id #7 [art] => Array ( ) [datei] =>   Der Herr der Ringe  39.90    Der kleine Hobbit  19.90    Grimms Maerchen  25.90    Elric von Melnibonee  29.90  )  for print_r($a_parser);

and Array() for print_r($art);

I suppose meaning that the array with which the data should be passed on is still empty.

ASKER CERTIFIED SOLUTION
Avatar of Roger Baklund
Roger Baklund
Flag of Norway image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hello cxr

I did that now, and it is working.  Thank's a lot for this.  Just a question, would you mind explaining a bit, but I suppose by thinking hard about it for a few more nights I should be able to figure it out myself at some point?
Example class:

$aaa = 123;
class foo {
    function bar($bbb) {
        $ccc = $bbb * 2;
        $this->ddd = $ccc * 10;
    }
}

$aaa is a global variable, it can be used within any function if it is declared in that function with "global $aaa".

$bbb is a parameter, it is local to the method foo:bar(), it can not be accessed outside this function. You can set this variable by calling the method, and within the method it works like a local variable, and can be changed.

$ccc is a local variable, it is local to the method foo:bar(), it can not be accessed outside this function. It can be read and changed within the method.

$this->ddd is an instance variable, it can be read and changed in any method in class foo. It can also be used outside the class, using the instance variable instead of this: after "$instance=new foo();" you can read and change $instance->ddd wherever $instance is accessible.

$this represents the "current" instance of an object. It can only be used inside class methods.
thank you, cxr, for taking the time to explain,

things are getting clearer.