<?php

// ------------------------------------------------------------------------- //
// Analyse d'un fichier XML.                                                 //
// ------------------------------------------------------------------------- //
// Auteur: J-Pierre DEZELUS                                                  //
// Email:  jpdezelus@phpinfo.net                                             //
// Web:    http://www.phpinfo.net/                                           //
// ------------------------------------------------------------------------- //
// Traduction de l'exemple donné dans la doc de PHP :                        //
//   http://www.php.net/manual/fr/ref.xml.php                                //
// ------------------------------------------------------------------------- //

// ----------------------------------------------------------------------------
function FichierAutorise($fichier) {
  
  
// seuls les fichiers locaux nous appartenant sont parsés
  
if (!eregi("^([a-z]+)://", $fichier) && fileowner($fichier) == getmyuid()) {
    return
true;
  }
  return
false;
}

// ----------------------------------------------------------------------------
function TraiterDebutBalise($analyseur_xml, $balise, $attributs) {
  
  
// Affichage de la balise de début
  
echo "&lt;<font color=\"#0000cc\">".$balise."</font>";
  
  
// Affichage des attributs
  
if (sizeof($attributs)) {
    while (list(
$k, $v) = each($attributs)) {
      echo
" <font color=\"#009900\">".$k."</font>=\"";
      echo
"<font color=\"#990000\">".$v."</font>\"";
    }
  }
  
  echo
"&gt;";
}

// ----------------------------------------------------------------------------
function TraiterFinBalise($analyseur_xml, $balise) {
  
// Affichage de la balise de fin
  
echo "&lt;/<font color=\"#0000cc\">".$balise."</font>&gt;";
}

// ----------------------------------------------------------------------------
function TraiterDonnee($analyseur_xml, $donnee) {
  
// Affichage de la donnée
  
echo "<b>".$donnee."</b>";
}

// ----------------------------------------------------------------------------
function TraiterCode($analyseur_xml, $target, $donnee) {
  
  switch (
strtolower($target)) {
    case
"php":
      global
$analyseur_xml_file;
      
// seuls les fichiers locaux nous appartenant sont parsés
      // pour les autres, on affiche leur code
      
if (FichierAutorise($analyseur_xml_file[$analyseur_xml])) {
        eval(
$donnee);
      } else {
        
printf("Code PHP non autorisé: <i>%s</i>",
        
htmlspecialchars($donnee));
      }
      break;
  }
}

// ----------------------------------------------------------------------------
function TraiterAutresCas($analyseur_xml, $donnee) {
  
  
// Affichage des données autres que balises et données utiles
  
if (substr($donnee, 0, 1) == "&" && substr($donnee, -1, 1) == ";") {
    
printf('<font color="#aa00aa">%s</font>', htmlspecialchars($donnee));
  } else {
    
printf('<font size="-1">%s</font>', htmlspecialchars($donnee));
  }
}

// ----------------------------------------------------------------------------
function TraiterReferenceExterne($analyseur_xml, $nomEntite, $base,
                                 
$systemId, $publicId) {
  
  if (
$systemId) {
    
    if (!list(
$analyseur_xml, $fp) = CreerAnalyseurXml($systemId)) {
      
printf("Impossible d'ouvrir l'entité %s à %s\n", $nomEntite, $systemId);
      return
false;
    }
    
    while (
$donnee = fread($fp, 4096)) {
      
      if (!
xml_parse($analyseur_xml, $donnee, feof($fp))) {
        
printf("Erreur XML '%s' à la ligne %d (Entité %s)\n",
               
xml_error_string(xml_get_error_code($analyseur_xml)),
               
xml_get_current_line_number($analyseur_xml), $nomEntite);
        
xml_parser_free($analyseur_xml);
        return
false;
      }
    }
    
    
xml_parser_free($analyseur_xml);
    return
true;
  
  }
  
  return
false;

}

// ----------------------------------------------------------------------------
function CreerAnalyseurXML($fichier) {
    
  global
$analyseur_xml_file;

  
// Création du parseur
  
$analyseur_xml = xml_parser_create();
    
  
// Vérifie la casse des balises
  
xml_parser_set_option($analyseur_xml, XML_OPTION_CASE_FOLDING, 1);

  
// Evènements sur une balise
  
xml_set_element_handler($analyseur_xml, "TraiterDebutBalise", "TraiterFinBalise");

  
// Evènement sur une donnée
  
xml_set_character_data_handler($analyseur_xml, "TraiterDonnee");

  
// Evènement sur instructions à exécuter
  
xml_set_processing_instruction_handler($analyseur_xml, "TraiterCode");
  
  
// Evènement par défaut
  
xml_set_default_handler($analyseur_xml, "TraiterAutresCas");

  
// Evènement sur référence externe
  
xml_set_external_entity_ref_handler($analyseur_xml, "TraiterReferenceExterne");
    
  if (!(
$fp = @fopen($fichier, "r"))) {
    return
false;
  }
  
  if (!
is_array($analyseur_xml_file)) {
    
settype($analyseur_xml_file, "array");
  }
    
  
$analyseur_xml_file[$analyseur_xml] = $fichier;
    
  return array(
$analyseur_xml, $fp);

}


// ----------------------------------------------------------------------------

// Fichier XML
$fichier = "http://www.phpinfo.net/news-phpinfo/news-phpinfo.rss";

// Création du parseur XML
if (!(list($analyseur_xml, $fp) = CreerAnalyseurXml($fichier))) {
  die(
"Impossible d'ouvrir le fichier ".$fichier);
}

// Lecture du fichier
echo "<PRE>";
while (
$buffer = fread($fp, 4096)) {
  
  
// Analyse du buffer
  
if (!xml_parse($analyseur_xml, $buffer, feof($fp))) {
    
    
// Traitement des erreurs
    
die(sprintf("Erreur XML '%s' à la ligne %d\n",
                
xml_error_string(xml_get_error_code($analyseur_xml)),
                
xml_get_current_line_number($analyseur_xml)));
  
  }

}
echo
"</PRE>";

echo
"Analyse terminée\n";

xml_parser_free($analyseur_xml);

// ----------------------------------------------------------------------------

?>