Précédent   Forum des professionnels en informatique > PHP > Langage > Regex
Regex Forum d'entraide sur les expressions rationnelles PHP. Avant de poster -> FAQ regex, Cours de regex et Sources de regex
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/09/2011, 12h24   #1
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Par défaut Parser à l'aide de DOM une balise XHTML imbriquée au lieu d'utiliser une Regex

Bonjour,

Ce post fait suite à mon précédent post sur l'extraction d'une chaîne contenant un mot précis ("schtroumpf" dans mes exemples) et va faire plaisir à Stealth qui de façon répétée prône DOM pour parser du xhtml au lieu d'utiliser des regex. (Je lancerai tantôt une discussion sur le thème regex versus DOM).

J'ai besoin — c'est d'ailleurs le point clé de mon projet — de parser à coup sûr des balises du style
Code :
1
2
3
 
<p (ou span) (éventuellement id="Identificateur") class="class1 class2 schtroumpf class3" (éventuellement style="règles de style")>(éventuellement <span class="Comment">Texte du commentaire</span>)
informations concernant la seule class schtroumpf</p> (ou </span>)
Je ne connais pas à l'avance les class autres que schtroumpf appliquées au paragraphe ou au span, ni l'identificateur éventuel, ni les règles de style, ni la présence ou non du commentaire.

Comment concrètement (s'il vous plaît !) procéder pour parser ces balises et récupérer :

1) la balise entière (que je dois remplacer après traitement des informations contenues dans la balise)

2) l'ensemble des class appliquées sous forme de chaîne (je peux avoir besoin de connaître les autres class appliquées en dehors de la class schtroumpf)

3) le texte du commentaire éventuel (que je dois traiter séparément)

4) les informations principales concernant la class schtroumpf, c'est-à-dire le contenu de la balise <p ou span class="xxx schtroumpf xxx"> [...] </p> ou </span>


Un grand, grand merci d'avance
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 14h42   #2
Membre Expert
 
Avatar de David Guillot
 
Homme David Guillot
Chef de projet en SSII
Inscription : mars 2004
Messages : 879
Détails du profil
Informations personnelles :
Nom : Homme David Guillot
Âge : 28
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Chef de projet en SSII
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : mars 2004
Messages : 879
Points : 1 149
Points : 1 149


Ma suggestion est clairement de regarder du côté de XPath. Regarde le plus ancien commentaire de cette page de la doc PHP, renseigne-toi sur la syntaxe XPath pour trouver des sous-éléments et des valeurs d'attributs, et tu auras gagné
__________________
Avant de poser une question ici :

Après résolution de votre question : un clic sur , un et un vote pour les personnes qui vous ont aidé
David Guillot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2011, 15h09   #3
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Merci David de ta réponse, et pardon de ne pas t'avoir répondu plus tôt (j'étais en déplacement)

Bien évidemment, j'avais consulté la doc Xpath et avais effectué pas mal d'essais infructueux avant d'adresser, en dernier recours, mon post de demande d'aide.

Apparemment, je suis encore très loin de maîtriser les concepts nécessaires.
J'ai cependant pu, au bout de quatre heures de tâtonnements, mettre en oeuvre la solution suivante (le code est inclus dans une fonction ; $text_area est le texte html à analyser :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
$text_area_xhtml = new DOMDocument();
		$text_area_xhtml -> loadHTML('<?xml encoding="UTF-8">'.$text_area);
		$text_area_xpath = new DOMXPath($text_area_xhtml);
 
		$with_class = $text_area_xpath -> query('//*[@class]//@*');
		foreach($with_class as $class)
		{
			$type_balise = $class -> nodeName;
			$contenu_balise = $class -> nodeValue;
 
			if(strpos($contenu_balise, 'My_class')!== false)
			{
				$balise_parente = $class -> parentNode;
 
				$balise_entiere = new DOMDocument();
				$balise_entiere -> appendChild($balise_entiere -> importNode($balise_parente, true));
				$balise_entiere = html_entity_decode($balise_entiere -> saveHTML());
				echo "Balise entière = " . $balise_entiere . "\n";
 
			}
 
		}
Ce code peut probablement être amélioré. Merci d'avance pour vos suggestions.


Concernant la question de fond regex ou DOM - XPath, je pense que j'utiliserai les regex lorsqu'elles peuvent facilement être définies et qu'elles permettent de sélectionner à coup sûr l'élément recherché, et que je réserverai DOM - Xpath pour les cas où la recherche par regex ne peut suffire.

Car, dans l'état actuel de ma pratique et de ma compréhension de DOM - Xpath, le coût horaire de cette approche est beaucoup trop élevé par rapport à l'approche regex. (En particulier, le blocage sur la question objet de ce post m'aura coûté cher.)


PS : Pourquoi echo supprime-t-il les caractères accentués ? Quand je demande
echo "balise entière = "
le résultat affiché est « balise entire ».
Comment faire pour que echo affiche les caractères accentués ?
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2011, 10h07   #4
Modérateur
 
Inscription : septembre 2010
Messages : 7 131
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 131
Points : 8 491
Points : 8 491
Code :
1
2
3
4
5
6
7
$doc = new DOMDocument();
$doc->loadHTMLFile('test.html');
 
$xpath = new DOMXpath($doc);
$query = $xpath->query(sprintf("//*[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", 'schtroumpf'));
 
echo $doc->saveHTML($query->item(0));
@Doc_Xhtml : pour l'encodage du HTML loadHTML fonctionne avec la balise <meta> et non pas une ouverture XML (même si ça marche ce n'est pas correct) et malheureusement DOMDocumentFragment n'est pas de méthode appendHTML
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2011, 19h00   #5
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Merci Stealth !

Comme flashub, je suis émerveillé et impressionné devant la puissance de DOM quand il est utilisé avec une telle virtuosité.

Je pense que je vais sérieusement approfondir la question pour tenter de n'utiliser in fine que des expressions DOM - Xpath - SimpleXML pour rechercher des éléments et n'utiliser des regex que pour l'analyse textuelle proprement dite des éléments trouvés.

Merci encore ! Et bravo !
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2011, 19h25   #6
Modérateur
 
Inscription : septembre 2010
Messages : 7 131
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 131
Points : 8 491
Points : 8 491
oui je compte sur toi pour porter le flambeau de ton pseudo,
alors avec DOMXPath y'a une méthode plus complète de Xpath c'est evaluate, et ta accès a d'autre fonction, par exemple compter combien y'a de div, au lieur de faire //div faire une boucle, incrémenté une variable, tu fait direct count(//div) et evaluate te renvoie par exemple 3, malheureusement sous PHP c'est que du Xpath 1.0
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/10/2011, 10h45   #7
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Citation:
Envoyé par stealth35 Voir le message
Code :
1
2
3
4
5
6
7
$doc = new DOMDocument();
$doc->loadHTMLFile('test.html');
 
$xpath = new DOMXpath($doc);
$query = $xpath->query(sprintf("//*[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", 'schtroumpf'));
 
echo $doc->saveHTML($query->item(0));
Bonjour Stealth,

Peux-tu me préciser la signification et le rôle du paramètre '%s' dans la fonction contains ci-dessus ?

Merci par avance
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/10/2011, 10h47   #8
Modérateur
 
Inscription : septembre 2010
Messages : 7 131
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 131
Points : 8 491
Points : 8 491
Citation:
Envoyé par Doc_xhtml Voir le message
Bonjour Stealth,

Peux-tu me préciser la signification et le rôle du paramètre '%s' dans la fonction contains ci-dessus ?

Merci par avance
c'est pour sprintf
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/10/2011, 11h42   #9
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Merci de ta prompte réponse.

Je comprends : %s signifie « remplacer par la chaîne donnée dans l'argument suivant le format, c'est-à-dire dans le cas présent "schtroumpf" ».

Mais pourquoi ne pas écrire directement
Code :
$query = $xpath->query(sprintf("//*[contains(concat(' ', normalize-space(@class), ' '), ' schtroumpf ')]"));
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/10/2011, 11h54   #10
Modérateur
 
Inscription : septembre 2010
Messages : 7 131
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 131
Points : 8 491
Points : 8 491
on fait comme on veux, j'ai juste plus jolie a la lecture surtout quand il faut mettre une variable
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/10/2011, 12h01   #11
Membre du Club
 
Homme Boris
conception et traitement de documents xhtml
Inscription : août 2011
Messages : 107
Détails du profil
Informations personnelles :
Nom : Homme Boris
Localisation : France, Seine et Marne (Île de France)

Informations professionnelles :
Activité : conception et traitement de documents xhtml
Secteur : Conseil

Informations forums :
Inscription : août 2011
Messages : 107
Points : 59
Points : 59
Compris !

Donc si
Code :
$className = 'schtroumpf'
il faut écrire
Code :
$query = $xpath->query(sprintf("//*[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", $className'));
Doc_xhtml est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h55.


 
 
 
 
Partenaires

Hébergement Web