SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Wizard Mincer's Avatar
    Join Date
    Mar 2001
    Location
    London | UK
    Posts
    1,140
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Smile Help parsing XML file please

    I've decided to re-attack an old project, but I'm having a little trouble with getting data from an XML file using the DOM functions.

    Firstly, here is a cut down version of the XML data:

    Code:
    <?xml version="1.0" encoding="iso-8859-1" ?>
    <!DOCTYPE groupstats SYSTEM "http://setiathome.ssl.berkeley.edu/xml/groupstats.dtd">
    
    <groupstats>
    
    <name>Phoenix Rising</name>
    <url>forums.teamphoenixrising.net/</url>
    <nummembers>615</nummembers>
    <numresults>3181466</numresults>
    <totalcpu> 2847.415 years</totalcpu>
    <founder>
    <name>riddlermarc</name>
    <url>forums.teamphoenixrising.net/index.php?s=</url>
    <profile><a href="http://setiathome.ssl.be...">View user profile</a></profile>
    </founder>
    <topmembers>
    <member>
    <name>Bob Whitaker</name>
    <url>forums.teamphoenixrising.net/forumdisplay.php?s=&forumid=6</url>
    <numresults>106630</numresults>
    <totalcpu>   59.494 years</totalcpu>
    <avecpu>4 hr 53 min 15.4 sec</avecpu>
    <datelastresult>Sun Aug 10 11:11:33 2003</datelastresult>
    <country>United Kingdom</country>
    </member>
    <member>
    <name>wolf</name>
    <url>forums.teamphoenixrising.net/index.php</url>
    <numresults>103504</numresults>
    <totalcpu>   99.235 years</totalcpu>
    <avecpu>8 hr 23 min 55.1 sec</avecpu>
    <datelastresult>Sun Aug 10 09:19:52 2003</datelastresult>
    <country>Germany</country>
    </member>
    
    </topmembers>
    
    </groupstats>
    Now, this is how I am grabbing the data for each individual member:

    PHP Code:
    $file './raw_data/raw_data_1060515107.xml' ;
    $raw_xml file_get_contents$file ) ;

    // Correct bad amphersands in Berkeley XML
    $raw_xml preg_replace('/&(?![0-9a-z]{1,6};)/is''&amp;'$raw_xml); 

    // create a DOM object from the xml
    $dom domxml_open_mem$raw_xml ) ;

    $root $dom->document_element();

    $member_nodes $root->get_elements_by_tagname'member' ) ;

    foreach( 
    $member_nodes as $member_node )
    {
        
    $member = array() ;

        
    $member_items $member_node->child_nodes() ;

        foreach( 
    $member_items as $item )
        {
            if( ! 
    $item->is_blank_node() )
            {
                
    $member[$item->node_name()] = trim$item->get_content() ) ;
            }
        }
        
    // This is where I will be processing each user's data for database entry
        // Currently I's just printing it out to screen
        
    echo '<pre>' ;
        
    print_r$member ) ;
        echo 
    '</pre>' ;

    I suppose the first question is 'Is this a good way to precess the file?'

    And secondly, I also need to get the information regarding the whole team. However, getting elements by tagname for tags called 'name' would end up giving me 600+ name elements (from the <member> elements as well as the root), when all I'm after is the first <name> from the <groupstats> element.

    Can anyone give me some pointers as to the best way to process this data?

    Many thanks,

    Matt. :)

  2. #2
    SitePoint Zealot sidhighwind's Avatar
    Join Date
    Aug 2003
    Location
    Indianapolis, IN
    Posts
    164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here is two functions that i use to parse xml data.

    PHP Code:
    /**
     * __get_xml_array($values, &$i)
     *
     * This is adds the contents of the return xml into the array for easier processing.
     *
     * @access private
     * @param array $values this is the xml data in an array
     * @param int $i this is the current location in the array
     * @return Array
     */
     
    function __get_xml_array($values, &$i)
     {
       
    $child = array();
       if (
    $values[$i]['value']) array_push($child$values[$i]['value']);
     
       while (++
    $i count($values))
       {
      switch (
    $values[$i]['type'])
      {
        case 
    'cdata':
       
    array_push($child$values[$i]['value']);
        break;
     
        case 
    'complete':
       
    $name $values[$i]['tag'];
       
    $child[$name]= $values[$i]['value'];
       if(
    $values[$i]['attributes'])
       {
         
    $child[$name] = $values[$i]['attributes'];
       }
        break;
     
        case 
    'open':
       
    $name $values[$i]['tag'];
       
    $size sizeof($child[$name]);
       if(
    $values[$i]['attributes'])
       {
         
    $child[$name][$size] = $values[$i]['attributes'];
          
    $child[$name][$size] = $this->__get_xml_array($values$i);
       }
       else
       {
          
    $child[$name][$size] = $this->__get_xml_array($values$i);
       }
        break;
     
        case 
    'close':
       return 
    $child;
        break;
      }
       }
       return 
    $child;
     }
     
     
    /**
     * _get_xml_array($data)
     *
     * This is adds the contents of the return xml into the array for easier processing.
     *
     * @access private
     * @param string $data this is the string of the xml data
     * @return Array
     */
     
    function _get_xml_array($data)
     {
       
    $values = array();
       
    $index = array();
       
    $array = array();
       
    $parser xml_parser_create();
       
    xml_parser_set_option($parserXML_OPTION_SKIP_WHITE1);
       
    xml_parser_set_option($parserXML_OPTION_CASE_FOLDING0);
       
    xml_parse_into_struct($parser$data$values$index);
       
    xml_parser_free($parser);
     
       
    $i 0;
     
       
    $name $values[$i]['tag'];
       
    $array[$name] = $values[$i]['attributes'];
       
    $array[$name] = $this->__get_xml_array($values$i);
     
       return 
    $array;
     } 
    what you do is call _get_xml_array() and pass in the xml data and it will return an array for you with all of the xml data.

    hope this helps..
    Jon Whitcraft :: It's the Bombdiggity!
    Web Applications Developer :: Zend Certified Engineer
    http://www.indycar.com

  3. #3
    SitePoint Wizard Mincer's Avatar
    Join Date
    Mar 2001
    Location
    London | UK
    Posts
    1,140
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sidhighwind
    what you do is call _get_xml_array() and pass in the xml data and it will return an array for you with all of the xml data.
    Unfortunately, when I call the function and pass it the aformentioned data, all I get is the following error:

    Code:
    Notice: Undefined index: attributes in E:\htdocs\stats\xml_stats_parser_2.php on line 89
    
    Fatal error: Call to a member function on a non-object in E:\htdocs\stats\xml_stats_parser_2.php on line 90
    Lines 89 and 90 are:

    PHP Code:
       $array[$name] = $values[$i]['attributes'];
       
    $array[$name] = $this->__get_xml_array($values$i); 
    Matt.

  4. #4
    SitePoint Zealot sidhighwind's Avatar
    Join Date
    Aug 2003
    Location
    Indianapolis, IN
    Posts
    164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok Sorry about that.

    I just pulled it out of one of my class files..

    you need to change line 90 to be like this
    PHP Code:
    $array[$name] = __get_xml_array($values$i); 
    I forgot to update that.

    That might fix it. If it doesnt then I'm at a loss for what is causing that Notice Error...but that shouldnt cause any problems...
    Jon Whitcraft :: It's the Bombdiggity!
    Web Applications Developer :: Zend Certified Engineer
    http://www.indycar.com

  5. #5
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    $array[$name] = __get_xml_array($values$i); 


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •