Page 1 of 1

Why is this code returning blank data to an array?

Posted: Sun Oct 15, 2006 1:08 pm
by impulse()
I know I've been advied on here many time to use return for transporting variables but I'm confortable with globals at the moment which is why I've used them in the below code.
The code is to try and pass all data parsed from an XML file into an array.

Code: Select all

if (!($xmlparser = xml_parser_create())) {   die ("Connect create parser"); }


          function start_tag($parser, $name, $attribs) {

            global $name;




           }


          function tag_contents($parser, $data) {

            global $container;
            global $tagCount;
            global $name;

            $container[$tagCount][$name] = $data;

          }




          function end_tag($parser, $name) {

            global $tagCount;
            $tagCount += 1;


          }





global $container;
print_r($container);




  xml_set_element_handler($xmlparser, "start_tag", "end_tag");

  xml_set_character_data_handler($xmlparser, "tag_contents");


    $filename = "data.xml";
    if (!($fp = fopen($filename, "r"))) { die("Cannot open ". $filename); }


  while ($data = fread($fp, 4096)) {
    $data = eregi_replace(">"."[[]]+"."<","><", $data);
    if (!xml_parse($xmlparser, $data, feof($fp))) {
      $reason = xml_error_string(xml_get_error_code($xmlparser));
      $reason .= xml_get_current_line_number($xmlparser); 
$reason .= xml_get_current_line_number($xmlparser);
      die ($reason);
    }
  }
  
  xml_parser_free($xmlparser);

Posted: Sun Oct 15, 2006 1:37 pm
by Mordred
You're dumping the variable before the XML has been parsed.
Use preg_*, they are smarter AND faster.

So, you're bold enough to mess with XML, but not bold enough to learn about functions? :)

Posted: Sun Oct 15, 2006 1:39 pm
by volka
You don't need to store all the contents of all tags. If you do there's no advantage over using dom (e.g. simplexml) but all the disadvantage of writing parser code yourself.
You only need to store the element content of <name>,<age>, <height> and <sex> when you're "within" a <friend> element.
Initialize some sort of container for the data you need to store for the current <friend> element. You will be notified via start_tag() when you "enter" a <friend> element (and also when you enter <name>,<age>, <height> and <sex>).
When you leave the <friend> element you can process the previously stored data and then discard the current container(i.e. the data of the <firend> element you just processed). You will be notifie via end_tag() when you "leave" an element.

Posted: Sun Oct 15, 2006 2:35 pm
by impulse()
I've been told that if I can learn how to insert XML data into a MySQL DB I can move into the programming department at the company where I work now for training. I work in technical support at the moment so you can understand my eagerness to complete this :). So that's why I've spent nearly every minute of the weekend trying everything I can to get this working.
So far the best results I've had is inserting every tags data onto a single line in a MySQL DB. I just can't get my head around seperating the values into the groups of <Friend> (1, 2, 3 or 4) and then <Name>, <Age> & <Sex>. I'd preferably like a layout like

Code: Select all

$container[1]['name'] = Something
$container[1]['age'] = Something
$container[1]['sex'] = Something
$container[2]['name'] = Something
$container[2]['age'] = Something

Posted: Sun Oct 15, 2006 2:39 pm
by Mordred
Statement accepted.
One would imagine you would benefit from asking a question, what what do I know... :)

Paste a short, but meaningful sample XML (using CODE tags please)

Posted: Sun Oct 15, 2006 2:47 pm
by impulse()

Code: Select all

<?xml version="1.0"?>
<friends>

  <friend>

    <name> Stephen </name>
    <age> 21 </age>
    <height> Tall </height>
    <sex> Male </sex>

  </friend>
And those tags repeat for each person.

Posted: Sun Oct 15, 2006 2:53 pm
by volka
impulse() wrote:I'd preferably like a layout like

Code: Select all

$container[1]['name'] = Something
$container[1]['age'] = Something
$container[1]['sex'] = Something
$container[2]['name'] = Something
$container[2]['age'] = Something
Again: You would use a DOM interface like simplexml if you wanted this. But you don't want it (or rather: have been told not to use it - you said so in another of numerous existing threads on the same topic)

You want:
<friend> -> $container = array();
$container['name'] = content of <name>
$container['age'] = content of <age>
$container['height'] = content of <height>
$container['sex'] = content of <sex>
</friend> -> process $container, then discard $container.