Domanda

Ho un sacco di documenti legacy simili a HTML.Ad esempio, sembrano HTML, ma hanno tag aggiuntivi che non fanno parte dell'HTML

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

Devo analizzare questi file.PHP è l'unico strumento disponibile.I documenti non si avvicinano all'XML ben formato.

Il mio pensiero originale era di utilizzare i metodi loadHTML su DOMDocument di PHP.Tuttavia, questi metodi soffocano i tag HTML di creazione e si rifiutano di analizzare la stringa/file.

$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 ....

L'unica soluzione che sono riuscito a trovare è pre-elaborare i file con funzioni di sostituzione delle stringhe che rimuoveranno i tag non validi e li sostituiranno con un tag HTML valido (forse uno span con un ID del nome del tag).

Esiste una soluzione più elegante?Un modo per far sapere a DOMDocument quali tag aggiuntivi considerare validi?Esiste una classe/oggetto di analisi HTML diversa e robusta disponibile per PHP?

(se non è ovvio, non considero le espressioni regolari una soluzione valida qui)

Aggiornamento:Le informazioni nei tag falsi fanno parte dell'obiettivo qui, quindi qualcosa come Tidy non è un'opzione.Inoltre, sto cercando qualcosa che faccia un certo livello, se non tutto, di pulizia della buona forma per me, motivo per cui in primo luogo stavo cercando il metodo loadHTML di DomDocument.

È stato utile?

Soluzione

Puoi eliminare gli avvisi con libxml_use_internal_errors, durante il caricamento del documento.Per esempio.:

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);

Se, per qualche motivo, hai bisogno di accedere agli avvisi, usa libxml_get_errors

Altri suggerimenti

Mi chiedo se passi l'HTML "cattivo". HTML ordinato potrebbe aiutare come primo passaggio?Potrebbe valere la pena dare un'occhiata, se riesci a far sì che il documento sia ben formato, forse potresti caricarlo come un normale file XML con DomDocument.

@Twan Non hai bisogno di un DTD per Domdocument per analizzare XML personalizzato.Basta usare DOMDocument->load(), e finché l'XML è ben formato, può leggerlo.

Una volta che i file sono ben formati, è allora che puoi iniziare a guardare i parser XML, prima di essere S.O.L.Lok Alejo ha detto, potresti guardare HTML ORDINATO, ma sembra che sia specifico dell'HTML e non so come andrebbe con i tuoi elementi personalizzati.

Non considero le espressioni regolari una soluzione valida qui

Finché non sarai ben formato, questa potrebbe essere la tua unica opzione.Una volta che hai portato i documenti in quella fase, sei a posto con le funzioni DOM.

Dai un'occhiata al Parser nel port PHP Fit.Il codice è pulito ed è stato originariamente progettato per caricare l'HTML sporco salvato da Word.È configurato per estrarre tabelle, ma può essere facilmente adattato.

Puoi vedere la fonte qui:http://gerd.exit0.net/pat/PHPFIT/PHPFIT-0.1.0/Parser.phps

Il test unitario ti mostrerà come usarlo:http://gerd.exit0.net/pat/PHPFIT/PHPFIT-0.1.0/test/parser.phps

La mia soluzione rapida e sporca a questo problema è stata eseguire un ciclo che corrispondesse al mio elenco di tag personalizzati con un'espressione regolare.L'espressione regolare non rileva i tag che contengono un altro tag personalizzato interno.

Quando c'è una corrispondenza, viene chiamata una funzione per elaborare quel tag e restituisce l'"HTML elaborato".Se quel tag personalizzato era all'interno di un altro tag personalizzato, il genitore diventa senza figli perché l'HTML effettivo è stato inserito al posto del figlio e verrà abbinato dall'espressione regolare ed elaborato alla successiva iterazione del ciclo.

Il ciclo termina quando non ci sono tag personalizzati senza figli da abbinare.Nel complesso è iterativo (un ciclo while) e non ricorsivo.

@Alan Tempesta

Il tuo commento sulla mia altra risposta mi ha fatto pensare:

Quando carichi un file HTML con DOMDocument, sembra che venga eseguito un certo livello di pulizia in merito a:ben formato, MA richiede che tutti i tag siano tag HTML legittimi.Sto cercando qualcosa che faccia il primo, ma non il secondo.(Alan Tempesta)

Esegui una regex (scusate!) sui tag e quando ne trova uno che non è un elemento HTML valido, sostituiscilo con un elemento valido che sai non esiste in nessuno dei documenti (blink mi viene in mente...), e assegnargli un valore di attributo con il nome dell'elemento illegale, in modo da poterlo ripristinare in seguito.per esempio:

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

ovviamente quel codice non funzionerà, ma hai un'idea generale?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top