transferring php xml parsing code into a class

Posted on 2009-02-23
Last Modified: 2012-06-21
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 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"?>


	<artikel nummer="5005">

		<name>Der Herr der Ringe</name>



	<artikel nummer="6006">

		<name>Der kleine Hobbit</name>



	<artikel nummer="3003">

		<name>Grimms Maerchen</name>



	<artikel nummer="4004">

		<name>Elric von Melnibonee</name>




/* the following version without a parser class displays the data alright*/

/* Artikel.class.php code */


	class Artikel {

		var $name;

		var $anzahl;

		var $preis;


		function Artikel($name, $preis) {

			$this->name = $name;

			$this->anzahl = 1;

			$this->preis = $preis;




/* code = Parser*/


	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);





	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 */



	include 'includes/';

	include 'includes/style.php';  //ausgelagerter link zu CSS stylesheet.




		echo $style_css; //variable in style.php

		//echo schreibeKorb();



		<div id="container">

        	<div id='header'>

                <h2>Folgende B&uuml;cher k&ouml;nnen Sie bestellen</h2>

                <div id='navTop'>


                    	<li><a href="warenkorb.php">Zum Warenkorb</a></li>

                        <li><a href="admin.php">Datenverwaltung</a></li>




            <div id='main'>


		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";







/*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 */




	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);



			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 code */


	include_once 'classes/Artikelparser.class.php';

	$datei = "./xml/artikeldaten.xml";

	$a_parser = new Artikelparser($datei);

	$parsing = $a_parser->aParser($datei);


	$art = $a_parser->getArtikelArray();



/* the code of artikel.php is unchanged */

Open in new window

Question by:Impylapa
    LVL 39

    Expert Comment

    by:Roger Baklund
    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);

    Author Comment

    Thank you cxr,

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


    Author Comment

    Hello again

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

    The print_r checks in 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.

    LVL 39

    Accepted Solution

    Change this:

    xml_parse($this->parser, $datei);

    ...into this:

    xml_parse($this->parser, $this->datei);

    And change this two places (lines 140 and 145):

    if($this->name == "ARTIKEL")

    ...into this:

    if($name == "ARTIKEL")

    Author Comment

    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?
    LVL 39

    Expert Comment

    by:Roger Baklund
    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.

    Author Comment

    thank you, cxr, for taking the time to explain,

    things are getting clearer.

    Featured Post

    Threat Intelligence Starter Resources

    Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

    Join & Write a Comment

    Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
    Active Directory replication delay is the cause to many problems.  Here is a super easy script to force Active Directory replication to all sites with by using an elevated PowerShell command prompt, and a tool to verify your changes.
    The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
    In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

    732 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now