Parsing OPML Files

The following functions (designed as class members) can parse (and write) OPML files in a way can understand:

  function parse( $szFilename ) {
    
assert( file_exists( $szFilename ) );
    
$oParser = xml_parser_create("ISO-8859-1");
    
$szData = implode( "",file($szFilename) );
    
xml_parse_into_struct( $oParser, $szData, $aValues );
    foreach(
$aValues as $aElement ) {
      if(
$aElement["tag"] === "OUTLINE" ) {
        
$szGUID = md5($aElement["attributes"]["XMLURL"]);
        
$this->m_aData[$szGUID] = $aElement["attributes"];
      }
    }
    
xml_parser_free( $oParser );
  }
// parse
  function serialize( $szFilename ) {
    
$hFile = fopen( $szFilename, "w" );
     
fputs( $hFile, '<?xml version="1.0" encoding="ISO-8859-1"?>' . "\n" );
     
fputs( $hFile, "<opml>\n  <body>\n" );
     foreach(
$this->m_aData as $aElement ) {
       
$szBuffer = "    <outline ";
       foreach(
$aElement as $szAttribute => $szValue ) {
         
$szAttribute = strtolower( $szAttribute );
         
$szAttribute = str_replace( "url", "Url", $szAttribute ); // readable names
         
$szValue = htmlentities( $szValue, ENT_COMPAT, "ISO-8859-1" );
         
// Pack \n and \r (usually inside DESCRIPTION attributes)
         
$szValue = strtr($szValue, array("\n" => "&#xA;", "\r" => "&#xD;"));
         
$szBuffer .= "$szAttribute=\"$szValue\" ";
       }
       
$szBuffer .= "/>\n";
       
fputs( $hFile, $szBuffer );
     }
     
fputs( $hFile, "  </body>\n</opml>" );
     
fclose( $hFile );
  }
// serialize