IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Parser à l'aide de DOM une balise XHTML imbriquée au lieu d'utiliser une Regex [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Homme Profil pro
    conception et traitement de documents xhtml
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 80
    Points
    80
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  2. #2
    Invité
    Invité(e)
    Par défaut


    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é

  3. #3
    Membre régulier
    Homme Profil pro
    conception et traitement de documents xhtml
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 80
    Points
    80
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ?

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  5. #5
    Membre régulier
    Homme Profil pro
    conception et traitement de documents xhtml
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 80
    Points
    80
    Par défaut
    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 !

  6. #6
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    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

  7. #7
    Membre régulier
    Homme Profil pro
    conception et traitement de documents xhtml
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 80
    Points
    80
    Par défaut
    Citation Envoyé par stealth35 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  8. #8
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    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

  9. #9
    Membre régulier
    Homme Profil pro
    conception et traitement de documents xhtml
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 80
    Points
    80
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    $query = $xpath->query(sprintf("//*[contains(concat(' ', normalize-space(@class), ' '), ' schtroumpf ')]"));

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    on fait comme on veux, j'ai juste plus jolie a la lecture surtout quand il faut mettre une variable

  11. #11
    Membre régulier
    Homme Profil pro
    conception et traitement de documents xhtml
    Inscrit en
    Août 2011
    Messages
    107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 80
    Points
    80
    Par défaut
    Compris !

    Donc si
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $className = 'schtroumpf'
    il faut écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $query = $xpath->query(sprintf("//*[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", $className'));

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 19/06/2015, 15h08
  2. Utiliser une balise <strong> ou non
    Par Teddy7 dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 24/01/2010, 10h22
  3. [XHTML] Insérer du code xml dans une page xhtml
    Par le-baron dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 09/07/2008, 17h00
  4. Réponses: 1
    Dernier message: 30/06/2008, 12h55
  5. [DOM] Changement dynamique de l'image de fond d'une balise <TD>
    Par Delphi-ne dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 03/02/2007, 19h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo