Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 265
  • Last Modified:

Object oriented PHP question -> Callback functions on XML not working

Hi,

I need to parse an XML document using the built-in PHP functions, but the parser needs to live inside a class.
For some reason, the callback functions don't seem to recognize the $this variable.

I've included some sample XML data and a very simple script describing the problem. Look in startElement() to see what I mean.

How can I make this work?



<?php
error_reporting(E_ALL);

class test {

      var $test = 'test';
      var $data = '<?xml version=\'1.0\'?>
                        <!DOCTYPE chapter SYSTEM "/just/a/test.dtd" [
                        <!ENTITY plainEntity "FOO entity">
                        <!ENTITY systemEntity SYSTEM "xmltest2.xml">
                        ]>
                        <chapter>
                        <TITLE>Title &plainEntity;</TITLE>
                        <para>
                         <informaltable>
                          <tgroup cols="3">
                           <tbody>
                            <row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
                            <row><entry>a2</entry><entry>c2</entry></row>
                            <row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
                           </tbody>
                          </tgroup>
                         </informaltable>
                        </para>
                        &systemEntity;
                        <section id="about">
                         <title>About this Document</title>
                        </section>
                        </chapter>';


      function Parse() {
            
            function startElement($parser, $name, $attrs) {
                  // THIS WORKS
                  echo "$name\n";
                  
                  // THIS DOESN'T WORK
                  //echo $this->test;
            }

            function endElement($parser, $name) {
                  // do more stuff
            }

            $xml_parser = xml_parser_create();
            xml_set_element_handler($xml_parser, "startElement", "endElement");

            if (!xml_parse($xml_parser, $this->data, true)) {
                  die(sprintf("XML error: %s at line %d",
                  xml_error_string(xml_get_error_code($xml_parser)),
                  xml_get_current_line_number($xml_parser)));
            }
            xml_parser_free($xml_parser);
      }
}

$a = new test();
$a->Parse();
?>
0
poisa
Asked:
poisa
  • 2
1 Solution
 
BatalfCommented:
Here's an example from the php manual(http://no.php.net/xml_parse) - slightly modificated according to your example.

<?

class CXml
{
   var $xml_data;
   var $obj_data;
   var $pointer;
   var $test = 'Hello';

   function CXml() { }
   
   function Set_xml_data( &$xml_data )
   {
       $this->index = 0;
       $this->pointer[] = &$this->obj_data;
   
       //strip white space between tags
       $this->xml_data = eregi_replace(">"."[[:space:]]+"."<","><",$xml_data);
       $this->xml_parser = xml_parser_create( "UTF-8" );
   
       xml_parser_set_option( $this->xml_parser, XML_OPTION_CASE_FOLDING, false );
       xml_set_object( $this->xml_parser, &$this );
       xml_set_element_handler( $this->xml_parser, "_startElement", "_endElement");
       xml_set_character_data_handler( $this->xml_parser, "_cData" );
       
       xml_parse( $this->xml_parser, $this->xml_data, true );
       xml_parser_free( $this->xml_parser );
   }
   
   function _startElement( $parser, $tag, $attributeList )
   {
       foreach( $attributeList as $name => $value ){
           $value = $this->_cleanString( $value );
           $object->$name = $value;
       }
       //replaces the special characters with the underscore (_) in tag name
       $tag = preg_replace("/[:\-\. ]/", "_", $tag);

       echo $tag."<br>";
       echo $this->test."<br>";    
       $this->index++;
   }

   function _endElement( $parser, $tag )
   {
       array_pop( $this->pointer );
       $this->index--;
   }
   
   function _cData( $parser, $data )
   {
       if (empty($this->pointer[$this->index])) {
           if (rtrim($data, "\n"))
               $this->pointer[$this->index] = $data;
       } else {
           $this->pointer[$this->index] .= $data;
       }
   }

   function _cleanString( $string )
   {
       return utf8_decode( trim( $string ) );
   }
}

$m_xml = new CXml();
$xml_data = '<?xml version=\'1.0\'?>
                    <!DOCTYPE chapter SYSTEM "/just/a/test.dtd" [
                    <!ENTITY plainEntity "FOO entity">
                    <!ENTITY systemEntity SYSTEM "xmltest2.xml">
                    ]>
                    <chapter>
                    <TITLE>Title &plainEntity;</TITLE>
                    <para>
                     <informaltable>
                      <tgroup cols="3">
                       <tbody>
                        <row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
                        <row><entry>a2</entry><entry>c2</entry></row>
                        <row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
                       </tbody>
                      </tgroup>
                     </informaltable>
                    </para>
                    &systemEntity;
                    <section id="about">
                     <title>About this Document</title>
                    </section>
                    </chapter>';

$m_xml->Set_XML_data( $xml_data );



?>
0
 
BatalfCommented:
Your code modificated:

The line

xml_set_object( $this->xml_parser, &$this );

did the trick.


<?php
error_reporting(E_ALL);

class test {

     var $test = 'test';
     var $data = '<?xml version=\'1.0\'?>
                    <!DOCTYPE chapter SYSTEM "/just/a/test.dtd" [
                    <!ENTITY plainEntity "FOO entity">
                    <!ENTITY systemEntity SYSTEM "xmltest2.xml">
                    ]>
                    <chapter>
                    <TITLE>Title &plainEntity;</TITLE>
                    <para>
                     <informaltable>
                      <tgroup cols="3">
                       <tbody>
                        <row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
                        <row><entry>a2</entry><entry>c2</entry></row>
                        <row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
                       </tbody>
                      </tgroup>
                     </informaltable>
                    </para>
                    &systemEntity;
                    <section id="about">
                     <title>About this Document</title>
                    </section>
                    </chapter>';
   
     
      function startElement($parser, $name, $attrs) {
       // THIS WORKS
       echo "$name\n";
       
       // THIS DOESN'T WORK
       //echo $this->test;
      }

      function endElement($parser, $name) {
       // do more stuff
      }

     function Parse() {
          $this->xml_parser = xml_parser_create();
          xml_set_element_handler($this->xml_parser, "startElement", "endElement");
          xml_set_object( $this->xml_parser, &$this );
          if (!xml_parse($this->xml_parser, $this->data, true)) {
               die(sprintf("XML error: %s at line %d",
               xml_error_string(xml_get_error_code($this->xml_parser)),
               xml_get_current_line_number($this->xml_parser)));
          }
          xml_parser_free($this->xml_parser);
     }
}

$a = new test();
$a->Parse();
?>
0
 
poisaAuthor Commented:
Works like a charm. Thanks!
0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now