PHP" jolie impression " HTML (pas bien rangé)

J'utilise L'extension DOM en PHP pour construire des documents HTML, et je veux que la sortie soit bien formatée (avec de nouvelles lignes et une indentation) afin qu'elle soit lisible, cependant, à partir des nombreux tests que j'ai fait:

  1. "formatOutput = true" ne fonctionne pas du tout avec saveHTML (), seulement saveXML ()
  2. Même si j'ai utilisé saveXML (), cela ne fonctionne toujours que sur les éléments créés via le DOM, pas sur les éléments inclus avec loadHTML (), même avec "preserveWhiteSpace = faux"

Si quelqu'un sait différemment j'aimerais vraiment savoir comment ils ont réussi à le faire fonctionner.

Donc, j'ai un document DOM, et j'utilise saveHTML() pour sortir le HTML. Comme il vient du DOM, je sais qu'il est valide, il n'est pas nécessaire de le "ranger" ou de le valider de quelque façon que ce soit.

Je cherche simplement un moyen d'obtenir une sortie bien formatée à partir de la sortie que je reçois de L'extension DOM.

NB. Comme vous l'avez peut-être deviné, je ne veux pas utiliser le bien rangé extension comme a) il fait beaucoup plus que j'en ai besoin aussi (le balisage est déjà valide) et b) il apporte des modifications au contenu HTML (comme le DOCTYPE HTML 5 et certains éléments).

Suivi:

OK, avec l'aide de la réponse ci-dessous, j'ai compris pourquoi L'extension DOM ne fonctionnait pas. Bien que l'exemple donné fonctionne, il ne fonctionnait toujours pas avec mon code. Avec l'aide de ce commentaire j'ai trouvé que si vous avez des nœuds de texte où isWhitespaceInElementContent() est true aucun formatage ne sera appliqué au-delà de ce point. Cela se produit indépendamment du fait que preserveWhiteSpace soit faux ou non. La solution consiste à supprimer tous ces nœuds (bien que je ne sois pas sûr que cela puisse avoir des effets négatifs sur le contenu réel).

28
demandé sur Jack Sleight 2009-04-20 17:21:03

3 réponses

Vous avez raison, il ne semble pas y avoir d'indentation pour HTML ( les autres sont également confus ). XML fonctionne, même avec du code chargé.

<?php
function tidyHTML($buffer) {
    // load our document into a DOM object
    $dom = new DOMDocument();
    // we want nice output
    $dom->preserveWhiteSpace = false;
    $dom->loadHTML($buffer);
    $dom->formatOutput = true;
    return($dom->saveHTML());
}

// start output buffering, using our nice
// callback function to format the output.
ob_start("tidyHTML");

?>
<html>
    <head>
    <title>foo bar</title><meta name="bar" value="foo"><body><h1>bar foo</h1><p>It's like comparing apples to oranges.</p></body></html>
<?php
// this will be called implicitly, but we'll
// call it manually to illustrate the point.
ob_end_flush();
?>

Résultat:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>foo bar</title>
<meta name="bar" value="foo">
</head>
<body>
<h1>bar foo</h1>
<p>It's like comparing apples to oranges.</p>
</body>
</html>

La même chose avec saveXML ()...

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
  <head>
    <title>foo bar</title>
    <meta name="bar" value="foo"/>
  </head>
  <body>
    <h1>bar foo</h1>
    <p>It's like comparing apples to oranges.</p>
  </body>
</html>

Probablement oublié de définir preserveWhiteSpace = false avant loadHTML?

Avertissement: j'ai volé la plupart du code de démonstration de tyson clugg / PHP manuel Commentaires . paresseux moi.


Mise à jour: je me souviens maintenant il y a quelques années j'ai essayé la même chose et a couru dans le même problème. j'ai corrigé cela en appliquant une solution de contournement sale (ce n'était pas critique pour les performances): j'ai juste converti entre SimpleXML et DOM jusqu'à ce que le problème disparaisse. je suppose que la conversion s'est débarrassée de ces nœuds. peut-être charger avec dom, importer avec simplexml_import_dom, puis sortir la chaîne, analyser à nouveau avec DOM et puis l'imprimer joliment. pour autant que je me souvienne, cela a fonctionné (mais c'était vraiment lent).

29
répondu stefs 2014-07-05 12:51:25

Quand j'ai eu un tas D'espaces de noms XML tidyHTML n'a pas aimé, est tombé sur ceci:

Http://gdatatips.blogspot.com/2008/11/xml-php-pretty-printer.html

5
répondu Garvin 2010-08-20 19:54:38

Vous pouvez utiliser le code de la hl_tidy fonction de la htmLawed bibliothèque.

// indent using one tab per indent, with all HTML being within an imaginary div
$out = hl_tidy($in, 't', 'div')
0
répondu user594694 2012-08-13 14:37:01