OPML Feed Reading for PHP (Technorati Favorites Example)

If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!

I wanted to share some of the work I have done while working on the favorite.me project. I will, over the next weeks, release most of the code but today I thought I would cover the OPML reader. It was something I originally had hoped to just find on phpclasses but nothing did what I wanted, so I wrote one from scratch. The class can be pointed (in theory) at any OPML feed and it will convert it into an array of values.

Here is the constructor for the class.

    function OPMLXmlParser($MyFeed){
        $this->XMLParser = xml_parser_create();  
        $this->feedUrl = $MyFeed;    
        xml_set_object($this->XMLParser,&$this);      
        xml_set_element_handler($this->XMLParser, "XmlParserFirstElement", 
					 "XmlParserendElement");      
        $this->data = array();
        if(!$this->ParseFeed()) {
        	$this->data = false;	
	}
    }

Firstly xml_parser_create is called to create the parsing resource. We then use xml_set_object to assign the callbacks to be against the class. Then xml_set_element_handler sets which methods within the class are called when opening and closing tags are discovered. These are called as the XML parser steps through the XML. Finally we call a class method ParseFeed which is described below.

    function ParseFeed(){
        if(($fp = fopen($this->feedUrl,"r")) === false) {
        	return false;	
		}
        while ($data = fread($fp, 4096)) {
            xml_parse($this->XMLParser, $data, feof($fp));
        }
        fclose($fp);
        xml_parser_free($this->XMLParser);
        return true;
    }

This is all simple stuff, we use the fopen,fread,fclose functions to open the URL (I love PHP for this..) read in the data then close the stream. We then parse the data as it comes in using xml_parse. And then close it down with xml_parser_free. The xml_parse function as it receives data will have been calling the callback functions that we setup earlier. Here they are defined.

    function XmlParserFirstElement($parser, $tagName, $attrs) {
        // Check the name of the tag
        switch(strtoupper($tagName)) {
        	case 'OUTLINE':
        		// If the opening tag is 'OUTLINE' store the attributes
        		$this->data[] = $attrs;
        		break;
		}
    }

This is what is called when opening tag is discovered, it supplies the that tag name and an array of attributes stored in key=>value form. This function checks the name of opening tag and stores the attribute data into a member variable if it matches correctly.

So how do you use it? Here is an example of how to read the OPML for my favorites on Technorati.

$test = new OPMLXmlParser("http://feeds.technorati.com/faves/TechFinder?
					format=opml");
$data = $test->getResults();
if($data) {
	viewArray($data);	
}

First the class must be created, then the results grabbed using getResults (it returns FALSE if it fails). I then use one of my helper functions viewArray to view the results. I have included the viewArray code within the code on my code bank section along with everyone else I have described here. The viewArray functions build a lovely table structure for viewing array hierarchies in an obvious layout (try it out its really worth it!).

P.S. The code in the code bank is fully commented, I have removed it for brevity here.

Post a Response