Question

J'ai un tas de documents existants qui ressemblent à HTML. Comme dans, ils ressemblent à HTML, mais ont des balises composées supplémentaires qui ne font pas partie de HTML

<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>

Je dois analyser ces fichiers. PHP est le seul outil disponible. Les documents ne s'approchent pas d'un XML bien formé.

À l’origine, je pensais utiliser les méthodes loadHTML sur le document DOM PHD de PHP. Cependant, ces méthodes gênent la création des balises HTML et refusent d'analyser la chaîne / le fichier.

$oDom = new DomDocument();
$oDom->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
//gives us
DOMDocument::loadHTML() [function.loadHTML]: Tag pseud-template invalid in Entity, line: 1 occured in ....

La seule solution que j'ai pu trouver consiste à prétraiter les fichiers avec des fonctions de remplacement de chaîne qui vont supprimer les balises non valides et les remplacer par une balise HTML valide (peut-être une étendue avec l'identifiant de la balise). nom).

Existe-t-il une solution plus élégante? Un moyen de permettre à DOMDocument de connaître les balises supplémentaires à considérer comme valides? Existe-t-il une classe / un objet d’analyse HTML robuste et différent pour PHP?

(si ce n'est pas évident, je ne considère pas les expressions régulières comme une solution valable ici)

Mettre à jour : les informations contenues dans les fausses balises font partie de l'objectif ici. Par conséquent, une solution telle que Tidy n'est pas une option. De plus, je suis à la recherche de quelque chose qui effectue un certain niveau, si ce n’est tout, de nettoyage de la bonne formation, c’est pourquoi j’ai utilisé la méthode loadHTML de DomDocument.

Était-ce utile?

La solution

Vous pouvez supprimer les avertissements avec libxml_use_internal_errors , lors du chargement du document. Par exemple:

libxml_use_internal_errors(true);
$doc = new DomDocument();
$doc->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
libxml_use_internal_errors(false);

Si, pour une raison quelconque, vous avez besoin d'accéder aux avertissements, utilisez libxml_get_errors

Autres conseils

Je me demande si on passe le "mauvais" HTML à travers la Remise HTML pourrait vous aider dans un premier temps? Cela vaut peut-être la peine d’être examiné. Si vous parvenez à bien former le document, vous pourrez peut-être le charger sous la forme d’un fichier XML standard avec DomDocument.

@Twan Vous n'avez pas besoin d'une DTD pour DOMDocument pour analyser le code XML personnalisé. Utilisez simplement DOMDocument- > load () , et tant que le XML est bien formé, il peut le lire.

Une fois que les fichiers sont bien formés, vous pouvez commencer à consulter les analyseurs syntaxiques XML. Avant cela, vous êtes S.O.L. Lok Alejo a déclaré que vous pourriez consulter HTML TIDY , mais il semble que ce soit spécifique HTML, et je ne sais pas comment cela se passerait avec vos éléments personnalisés.

  

Je ne considère pas les expressions régulières comme une solution valable ici

Tant que vous ne serez pas bien formé, cela pourrait être votre seule option. Une fois que les documents sont arrivés à ce stade, les fonctions DOM apparaissent clairement.

Jetez un coup d’œil à l’analyseur dans le port PHP Fit. Le code est propre et a été conçu à l'origine pour charger le code HTML sale enregistré par Word. Il est configuré pour extraire les tables, mais peut facilement être adapté.

Vous pouvez voir la source ici: http://gerd.exit0.net/pat/PHPFIT/ PHPFIT-0.1.0 / Parser.phps

Le test unitaire va vous montrer comment l'utiliser: http://gerd.exit0.net/pat/ PHPFIT / PHPFIT-0.1.0 / test / parser.phps

Ma solution rapide et sale à ce problème consistait à exécuter une boucle qui correspond à ma liste de balises personnalisées avec une expression régulière. L'expression rationnelle n'intercepte pas les balises contenant une autre balise personnalisée interne.

En cas de correspondance, une fonction permettant de traiter cette balise est appelée et renvoie le "HTML traité". Si cette balise personnalisée se trouvait dans une autre balise personnalisée, le parent devient sans enfant du fait que le code HTML réel a été inséré à la place de l'enfant et qu'il sera associé à l'expression rationnelle et traité à la prochaine itération de la boucle.

La boucle se termine lorsqu'il n'y a pas de balises personnalisées sans enfant à faire correspondre. Globalement, c'est itératif (une boucle while) et non récursif.

@Alan Storm

Votre commentaire sur mon autre réponse m'a amené à réfléchir:

  

Lorsque vous chargez un fichier HTML avec DOMDocument, il semble effectuer un certain niveau de nettoyage pour bien former, mais BUT requiert que toutes vos balises soient des balises HTML légitimes. Je cherche quelque chose qui fait l'ancien, mais pas le plus tard. (Alan Storm)

Exécuter une regex (désolé!) sur les balises, et quand il en trouve un qui n'est pas un élément HTML valide, remplacez-le par un élément valide qui n'existe dans aucun des documents ( blink vient à l’esprit ...), et donnez-lui une valeur d’attribut avec le nom de l’élément illégal, afin que vous puissiez le réactiver ultérieurement. par exemple:

$code = str_replace("<pseudo-tag>", "<blink rel=\"pseudo-tag\">", $code);
// and then back again...
$code = preg_replace('<blink rel="(.*?)">', '<\1>', $code);

évidemment, ce code ne fonctionnera pas, mais vous avez une idée générale?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top