Nokogiri genera HTML non valido?

Ho bisogno di elaborare un documento HTML e inserire alcuni nodes in alcuni punti. Il contenuto che sto elaborando non è valido, ma Nokogiri è abbastanza intelligente da capire cosa dovrebbe essere. Il problema è che non voglio cambiare la formattazione del documento originale, a parte i pezzi che sto inserendo.

Ecco un esempio:

require 'nokogiri' orig_html = '    1 

2

3 ' puts Nokogiri::HTML(orig_html).inner_html # >> # >> # >> # >> # >> # >> # >> 1 # >>

2

# >> 3 # >> # >>

Mi piacerebbe che l’output fosse lo stesso dell’input. Il problema è che non posso avere

all’interno di . La mia inclinazione è quella di passare a XML, ma poi ci sono tag non validi come il tag , che non è chiuso. L’HTML è abbastanza intelligente da riconoscerlo, ma XML non lo è.

Nokogiri sta correggendo l’HTML malformato per renderlo analizzabile. Dopo che è finito, il DOM è in uno stato ragionevole, ma il documento originale non è più disponibile da Nokogiri.

Se vuoi che l’originale sia intatto, devi renderlo valido prima di passarlo a Nokogiri, quindi puoi manipolarlo usando i metodi di Nokogiri. Normalmente lo farei usando alcune espressioni regolari per trovare i punti problematici e aggiungere / regolare i tag o i tag di chiusura associati, per consentire a Nokogiri di analizzare senza la necessità di sistemare le cose.

Non è un caso che HTML sia più intelligente di XML, è un caso di Nokogiri che onora lo spirito delle specifiche XML, che è rigido, e innalza i flag popolando la matrice degli errori con gli errori quando il file non è valido. L’HTML ha una specifica meno rigida e, poiché i browser sono (troppo) indulgenti durante l’analisi e la visualizzazione di HTML, Nokogiri segue un po ‘, risolve e quindi popola la matrice degli errors . (In entrambi i casi, puoi controllare quella matrice per vedere cosa c’è che non va.)

 require 'nokogiri' orig_html = '    1 

2

3 ' doc = Nokogiri::HTML(orig_html) doc.errors

doc.errors contiene:

 [ [0] # ] 

Ecco come utilizzare Nokogiri per correggere il codice HTML di esempio:

 doc = Nokogiri::HTML(orig_html) p = doc.at('b+p') p.previous_sibling.remove 

Questo è l’HTML a questo punto:

        1 

2

3

continuando:

 p.inner_html = "#{p.content}" puts doc.to_html 

Questo è l’HTML risultante:

        1 

2

3

È piuttosto ovvio che l’HTML di esempio non è quello con cui stai veramente lavorando, quindi dovrai modificare gli accessor per individuare i tag che devono essere modificati, ma questo dovrebbe farti andare avanti.

Quanto sopra funziona per la situazione specifica sopra, ma non per un caso come di seguito.

  orig_html = '    1 this is a bold 

This is a paragraph

3 ' doc = Nokogiri::HTML(orig_html) p = doc.at('b+p') p.previous_sibling.remove p.inner_html = "#{p.content}" # !> mismatched indentations at 'end' with 'def' at 17 puts doc.to_html

L’HTML risultante:

         1 

This is a paragraph

3