Bonjour,
J'essaie d'utiliser DOMDocument pour parser une chaine HTML, et ajouter "à la volée" des styles CSS inline, en fonction du nom des balises, des classes ou id des balises.
Je débute avec DOMDocument...
Voici un exemple de code : test.php
Ce code est en partie fonctionnel :
Code php : 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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 <?php header('Content-type:text/html; charset=UTF-8'); // encodage UTF-8 error_reporting(E_ALL); // en TEST !! ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>DOMDocument : ajouter des styles CSS inline à la volée</title> </head> <body> <?php // --------------------- // 1- CONTENU HTML à parser // --------------------- $contentHTML = <<<EOT <article class="artListe" id="article118"> <header> <h1 style="padding:10px;background:yellow;">header h1 : Lorem Ipsum</h1> </header> <div class="artContenu"> <figure> <img src="https://www.developpez.net/forums/avatars/256045-jreaux62.gif?dateline=1487190201" alt="jreaux62" /> </figure> <div> <img src="https://www.developpez.net/forums/avatars/256045-jreaux62.gif?dateline=1487190201" alt="jreaux62" /> <h1>div h1 : Sub carnifex patratis maestitiam multos</h1> <h2>div h2 : Zenonem Attico audiebamus amaret mentitum</h2> <h3>div h3 : Senatores se hortaretur Maximino cum</h3> <h4>div h4 : Non et in quibusque incidissent</h4> <p>div p : Validis Arabia hanc castrisque saepe ad contigua est Nabataeis nomine.</p> <p class="pClass1">div p (pClass1) : Validis Arabia hanc castrisque saepe ad contigua est Nabataeis nomine.</p> <p class="pClass1 pClass2">div p (pClass1 pClass2) : Cum neque commentum nec conduntur quoniam hoc munimentum Paleas omne.</p> </div> </div> <footer> <p>footer p : Lorem Ipsum</p> </footer> </article> EOT; // --------------------- // 2- STYLES CSS à appliquer : // --------------------- $tag_css['header'] = array( 'h1' => 'font-size:240%;color:orange;', ); $tag_css['div'] = array( 'figure' => 'border:1px solid red;margin:20px;padding:20px;', 'img' => 'border:1px solid lightblue;margin:20px;padding:20px;background:lightgreen;', 'p' => 'font-size:100%;color:grey;', 'h1' => 'font-size:180%;color:green;', 'h2' => 'font-size:160%;color:blue;', 'h3' => 'font-size:140%;color:orange;', 'h4' => 'font-size:120%;color:purple;', ); $tag_css['footer'] = array( 'p' => 'font-size:90%;background:orange;color:#fff;text-align:center;', ); // --------------------- // 3- PARSER avec DOMDocument // --------------------- $domDocument = new DOMDocument; // on évite l'affichage d'erreurs html en les redirigeant vers le gestionnaire d'erreurs de libxml. On sauvegarde l'ancien état dans $state. $state = libxml_use_internal_errors(true); // on charge le contenu HTML $domDocument->loadHTML( $contentHTML, LIBXML_HTML_NOIMPLIED ); $domDocument->preserveWhiteSpace = false; // on restitue l'ancien état du gestionnaire d'erreurs de libxml libxml_use_internal_errors($state); // discard white space // ------------------------- // 4- Recherche par TAG NAME // ------------------------- // 4.1- article $domArticle = $domDocument->getElementsByTagName('article'); // --------------------- // 4.2- childNodes de article : header / div / footer foreach( $domArticle->item(0)->childNodes as $ArtChildNode ) { if( !empty( $ArtChildNode->tagName ) ) // header / div / footer { // echo '<pre>'; print_r( $ArtChildNode->tagName ); echo '</pre>'; // ----------------- foreach( $tag_css[$ArtChildNode->tagName] as $tag => $css ) { $nodeList = $ArtChildNode->getElementsByTagName( $tag ); foreach( $nodeList as $node ) { $node->setAttribute( 'style', $node->getAttribute('style').$css ); } } // ----------------- } } // ------------------------- // 5- Recherche par CLASS // ------------------------- // on crée un objet DOMXPath pour pouvoir faire des requêtes XPath sur l'arbre DOM. $domXP = new DOMXPath($domDocument); $nodeList = $domXP->query('//*[@class="pClass1"]'); foreach ($nodeList as $node) { $node->setAttribute('style', $node->getAttribute('style').'font-weight:bold;color:pink;'); } // ------------------------- // 6- on reconstitue la chaîne html en concaténant les noeuds enfant de l'élément racine. // ------------------------- $contentHTMLCSS = ''; foreach ($domDocument->documentElement->childNodes as $node) { $contentHTMLCSS .= $domDocument->saveHTML($node); } echo $contentHTMLCSS; // ------------------------- ?> </body> </html>
- pour l'instant, j'y arrive à peu près avec les noms des balises.
- j'arrrive à traiter séparément les noeuds-enfants de <article> (header / div / footer)
SAUF QUE...
QUESTION 1 : Méthode
- est-ce la bonne méthode ? (car j'ai l'impression de construire une usine à gaz)
QUESTION 2 : Recherche par TAG NAME
- si on prend l'exemple des 2 balises <img>, j'aimerai pouvoir différencier (styler différemment) celle dans <figure> et celle dans <div>
- C'est-à-dire comment "déterminer" et traiter séparément les noeuds-enfants de <div class="artContenu"> ?
QUESTION 3 : Recherche par CLASS
- j'arrive à styler pour <p class="pClass1">,
- mais pas pour <p class="pClass1 pClass2"> (quand il y a plusieurs classes)
- Comment faire ? (je ne maitrise pas les query DOMXPath)
Merci de vos éclairages...
N.B. Pour info, l'Objectif : pouvoir envoyer des emails / newsletters HTML, formatés avec styles personnalisés.
Partager