Contrôle de présence d'une balise dans un flux XML

WRInaute occasionnel
Salut,

J'ai un souci qui me prend la tête depuis plusieurs jours.

dans le cadre d'un projet, je vais permettre à tous de charger un flux XML à travers un formulaire. Pas de souci, je contrôle si l'URL est accessible, s'il s'agit bien d'un flux... mais comme tout le monde risque de soumettre un peu tout et n'importe quoi, je dois aussi m'assurer que la structure du flux est bonne avec la présence des balises title, link et description

Mon souci, impossible de contrôler si mes trois balises sont bien présentes. Voici mon code, qui pourra peut être en aider certains :
Code:
//-- Nombre maximum de lignes qui s'affichent sur votre site
$max_lignes = 1;

$adresse_flux = $_POST['urlrss']; //-- Adresse complète du flux RSS.

//-- Nom des Balises à afficher dans le résumé du flux ( voir (1) )
$balises = array('title', 'link', 'description');


function readFeedCurl ( $url, $objets, $nb_items ) {

	$msg_error = 'Erreur';

	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$data = curl_exec ($curl);
	curl_close ($curl);

	if ( !empty ( $data ) ) {

		$pos = strpos ( $data, '<?xml version="1.0" encoding="utf-8"?>' );

		if ( $pos === false ) {

  			echo utf8_encode ( $msg_error );

		}

		else {

			@$xml = new simpleXMLElement ( $data );

			$i = 0;
			$resultat = array();

			//-- On boucle pour récupérer les différents <item>
			foreach ( $xml -> channel -> item as $item ) {

				//-- On boucle pour automatiser les récupération des balises en fonction du tableau
				foreach ( $objets as $objet ) {

					$resultat[$i][$objet] = $item->$objet;

					if ( $resultat[$i][$objet] ) { return true; }
						else {
							echo utf8_encode ( $msg_error );
							break;
						}

				}

				$i++;

				if ( $i > $nb_items ) { break; }

			}

			if ( empty ( $resultat[0] ) ) { echo utf8_encode ( $msg_error ); }

		}

	}

	else {

		echo utf8_encode ( $msg_error );

	}

}

C'est au niveau de ces lignes que je ne sais pas comment vérifier si la balise existe ou non :
Code:
début des soucis      if ( $resultat[$i][$objet] ) { return true; }
                  else {
                     echo utf8_encode ( $msg_error );
                     break;
Fin des soucis            }
Pour le reste, tout est ok. Je veux pas que tout parte en sucette si au lien d'utiliser les balises standard, un flux utilise des balises maison du type "titre", "lien" et "texte", ce qui rendrait le parsing problématique.

Je précise qu'il s'agit bien entendu de flux distants qui ne sont pas les miens, sinon, je ne me poserait même pas la question de la conformité du balisage.

Si vous avez la soluce, merci.
 
WRInaute impliqué
Je ne suis pas expert en flux xml, mais peut-être peux-tu contourner le pbm de la façon suivante :

Dans ton formulaire, tu dis explicitement que, par défaut, tu interroges telles et telles balises. Si ces balises sont absentes du flux, tu invites les utilisateurs à saisir les balises correspondantes qu'ils utilisent dans leurs flux. Ensuite, tu adaptes automatiquement le script qui parse ce flux.
 
WRInaute occasionnel
Salut,

Je te remercie de ta réponse. L'idée est pas mauvaise, mais comme souvent, ça complexifie les inscriptions et les utilisateurs risquent de renseigner n'importe quoi.

Un principe auquel je tiens : ne jamais faire confiance à la saisie utilisateur (pas l'utilisateur, sa saisie hein !).

D'autre part, je pense qu'un certain nombres d'utilisateurs de flux, notamment avec les CMS et autres projets open source, je savent pas comment s'articule leurs flux.

A la limite, il faut mieux juste contrôler que l'URL est valide et répond, et vérifier ensuite manuellement la validité du flux. Mais c'est une perte de temps dans la mesure où l'on peut le faire automatiquement. Une vérif manuelle du flux n'apporte aucune plus value, mieux vaut consacrer ce temps à du travail rédactionnel par exemple.

Merci quand même d'avoir pris le temps de répondre. Si quelqu'un a une soluce, j'ai toujours pas trouvé.
 
WRInaute occasionnel
Personne n'a eu le problème alors ? :cry:

Je suis quand même pas le seul à vouloir m'assurer du format des balises qui constituent un document XML ?
 
Nouveau WRInaute
Je vois pas pourquoi tu te prend le curl :lol: : ( et aussi tu utilise curl), je pense que tu doit tout simplement parser ton xml avec du dom voila un exemple

Code:
$dom = new DOMDocument();
                        if (!$dom->load($gurl)) {
                            die('Impossible de charger le fichier XML');
                        }
                        
                        // root node product
                        $itemList = $dom->getElementsByTagName('product');
                        foreach ($itemList as $item) {
                            
                            // prend la section name 
                            $titre = $item->getElementsByTagName('name');
                            // si le noeud existe 
                            if ($titre->length > 0) {
                                $pTitre= $titre->item(0)->nodeValue;
                            } else { 
                             // la tu met ce que tu veux
                             }
                        
                        }

sinon pour d'autre détails c'est par la

http://php.net/manual/en/domdocument.getelementsbytagname.php
 
WRInaute occasionnel
Salut,

Merci de ta réponse, je n'avais pas pensé à passer par l'arbre Dom, impeccable, bouclé en deux minutes. Je ne voyais pas l'évidence. Pour ceux que ça intéresse, voici la fonction complète :

Cette fonction permet de tester le format et la disponibilité d'un flux XML qui serait soumis par exemple via un formulaire sur un annuaire ou autre site. Si vous avez décider de parser uniquement des flux qui comportent les balises standard (ou autres balises, selon votre choix), voici comment vérifier que le flux soumis respecte vos contraintes.

Code:
	//-- Zone de paramétrage------->

	$adresse_flux = http://www.example.com/flux.xml; //-- Adresse complète du flux RSS.
	$balises = array ( 'title', 'link', 'description' ); //-- Nom des Balises à parser )

	$msg_error = '<li>Votre message d'erreur</li>';

	if ( !readFeedDom ( $adresse_flux, $balises ) ) {
		echo utf8_encode ( $msg_error );
	}

function readFeedDom ( $url, $objets ) {

	$dom = new DOMDocument();

	if ( @!$dom -> load ( $url ) ) {
		return false;
	}
                        
	// root node product
	$itemList = $dom->getElementsByTagName('item');

	foreach ( $itemList as $item ) {
                            
		foreach ( $objets as $objet ) { //-- On boucle pour automatiser les récupération des balises en fonction du tableau

			$resultat[$objet] = $item -> getElementsByTagName ( $objet );

			if ( $resultat[$objet] -> length > 0 ) {}
				else {
					return false;
					break;
				}

		}

		return true;

	}

}
Vous pouvez adapter la fonction pour que au lieu d'afficher un message comme quoi le flux est conforme, lire directement le flux ou donner un ordre d'insertion en base de données.

A vous de voir. Et merci à calligan pour cette piste que j'avais complètement négligé :wink:
 
Discussions similaires
Haut