returned xml array troubles

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
neophyte
DevNet Resident
Posts: 1537
Joined: Tue Jan 20, 2004 4:58 pm
Location: Minnesota

returned xml array troubles

Post by neophyte »

Hey guys, I'm working through this tutorial from the Zend.com. I'm trying to make the tutorial practical for a real life scenario. Here's a sample XML:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">

<channel>
  <title>My Site</title> 
  <link>http://www.mysite.com</link> 
  <description>Visit my site</description> 
  <language>en-us</language> 
  <copyright>(C) your grandma</copyright> 
  <image>
  <title>Greetings</title>
  <link>http://www.mysite.com/</link>
  <url>http://www.mysite.com/images/logo.jpg</url>
  </image>

    
<item>
<title>Article one</title>
<link>http://www.mysite.com/article.html</link>
<pubDate>Sat, 28 Jan 2006 11:25:00 EST</pubDate>
<description><![CDATA[<p>Read this article to find out how</p>]]></description>
<category>How to</category> 
<guid isPermaLink="false">http://www.mysite.com/3172.html</guid> 
</item>
</channel>
When I run the parser code below, the first "item" title would be "My Site Article one". Thus incorrectly combining the site title and the first item's title. The second item (if the example above had one) would out put as expected -- "Article Two".

The question is how do I get the parser to make a two tiered array? Something like:

Code: Select all

array(   'site description',
                      array(  array( 'item'),
                                  array('item')
                                  array('item')
                               );
       );
I'm not sure where to get a variable to track what level I'm on or if I need a new array or whatever.

Code: Select all

<?php 
// the xml file we want to parse
$xmlSource="rssTest.xml";

$title="";
$link="";
$pubDate="";
$description="";
$category="";

$currentElement="";	//holds the name of the current element
$depth = array();
$items=array(); 	//array to hold all the movie data


function startElement($parser,$name,$attr){
		
	$GLOBALS['currentElement']=$name;	

}


function endElement($parser,$name){
	
	$elements=array('title', 'link',  'pubDate', 'description', 'category');     
	
     if(strcmp($name,"item")==0){
     
			foreach($elements as $element){
				$temp[$element]=$GLOBALS[$element];							
			}
///HERE's WHERE IT GOES INTO THE ARRAY
			 $GLOBALS['items'][]=$temp;
			
            $GLOBALS['title']="";

            $GLOBALS['link']="";

            $GLOBALS['pubDate']="";

            $GLOBALS['description']="";
            
            $GLOBALS['category']= "";
      }



}


function characterData($parser, $data) {
        $elements=array('title', 'link',  'pubDate', 'description', 'category'); 
		
        foreach ($elements as $element) {
            if ($GLOBALS["currentElement"] == $element ) {

					$GLOBALS[$element] .= $data;

            }
        }
    }


function parseFile(){
	global $xmlSource,$items;
	
	/*Creating the xml parser*/
	$xml_parser=xml_parser_create();
	
	/*Register the handlers*/
	xml_set_element_handler($xml_parser,"startElement","endElement");
	xml_set_character_data_handler($xml_parser,"characterData");
	
	/*Disables case-folding. Needed for this example*/
	xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,false);
	
	/*Open the xml file and feed it to the parser in 4k blocks*/
   if(!($fp=fopen($xmlSource,"r"))){
      die("Cannot open  $xmlSource  ");
   }
   $x =0;
   while(($data=fread($fp,4096))){
      if(!xml_parse($xml_parser,$data,feof($fp))){
	     die(sprintf("XML error at line %d column %d ", 
                      xml_get_current_line_number($xml_parser), 
                      xml_get_current_column_number($xml_parser)));
	  }
	  $x++;
   }
     
	 /*Finish ! we free the parser and returns the array*/
	 xml_parser_free($xml_parser);
	 
	 return $items;
	
}//end parseFile()



/***************************************************************************************************
		Calling the parseFile() and getting the result out in a simple html-table
***************************************************************************************************/

$result=parseFile();

print '<table border="1">';
foreach($result as $arr){

	/*check on movieId to see if we reached a new movie. 
	*	If so we print out the movieName
	*/
		if(strcmp($id,$arr["title"])!=0){
			print '
		<tr>
			<td colspan="3"><b><a href="'.$arr['link'].'">'.$arr["title"].'</a></b></td>	
		</tr>
		<tr>
			<td colspan="3">'.$arr["description"].'</td>	
		</tr>
		';
		
		}




}

print '</table>';
?>
Thanks for your help
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

wow! serendipity...I'm doing the same thing today :P

here's what I found that needs a lil' bit of tweaking but I"m on the right track with it:

http://us2.php.net/simplexml

example:

Code: Select all

$someStr = file_get_contents("test2.xml");
$xml = simplexml_load_string($someStr);
echo "<pre>";
print_r($xml);
echo "</pre>";
User avatar
neophyte
DevNet Resident
Posts: 1537
Joined: Tue Jan 20, 2004 4:58 pm
Location: Minnesota

Post by neophyte »

Bummer running php4! SimpleXML is for PHP5! I tried:

http://magpierss.sourceforge.net

Works brilliantly!

Using it this way for local on server rss feeds:

Code: Select all

<?php
require_once('magpierss/rss_parse.inc');
$source = file_get_contents('/home/tna/www/rssTest.xml');
		$rss = new MagpieRSS($source);								
	var_dump($rss->items);

?>
//Minor modification to rss_parse.inc needed... Path needs to be defined.

Code: Select all

if(!defined('MAGPIE_DIR'){
define('MAGPIE_DIR', '');
}

However if someone does figure out the solution to the previous problem, I would very much love to see the solution. Today has been about learning XML.
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

Neophyte does that library work with tag attributes?

simplexml only seems to put data that is in the node containers into the array.

I'd like something that will do both.
User avatar
neophyte
DevNet Resident
Posts: 1537
Joined: Tue Jan 20, 2004 4:58 pm
Location: Minnesota

Post by neophyte »

I lucked out, the RSS feeds I was working with don't need attribute support. But it looks like according to their site magpierss has limited attribute support. The projects to do list includes improving attribute support. Can't hurt to try...
Post Reply