2011-09-03 6 views
10

Vorrei interrogare un documento HTML come XML (ad esempio con XPath), quindi ho bisogno di passare l'HTML attraverso una qualche forma di HTML cleaner.Esistono parser Java HTML in cui i nodi generati conservano gli indici nel testo originale?

Ma vorrei anche apportare modifiche alla stringa di origine originale in base ai risultati delle query.

Esiste un parser Java HTML che mantiene gli indici sulla stringa di origine originale, quindi posso individuare un nodo e modificare la parte corretta della stringa originale?

Cheers.

+2

Non sarebbe meglio lavorare con il DOM e quindi convertirlo in una rappresentazione String? Avrai una versione più pulita dell'HTML insieme alle tue modifiche. C'è una ragione specifica per cui è necessario modificare la stringa sorgente originale? –

+0

Posso pensarne uno. Rende più facile capire quali modifiche sostanziali sono state apportate se non si è costretti a guadare attraverso una serie di modifiche testuali che sono solo il risultato di unpare che rende l'XML un po 'diverso. –

+0

Vivin - Sto provando a "pulire" determinati elementi sensibili dalle pagine HTML in modo che possa eseguire altri test di analisi rispetto all'HT originale (con i dati sensibili sovrascritti con 999 o xxx, ecc.). Inoltre, voglio essere in grado di eseguire test diversi sia in Java che in Javascript, quindi la sorgente originale è il miglior punto di partenza per me, poiché i parser Java HTML e il parser HTML di ogni browser possono generare DOM diversi (anche se probabilmente non si dovrebbe). –

risposta

0

Non conosco la parte "conserva indici per il testo originale" ma Jericho è una libreria di parser HTML molto buona.

Ecco un esempio di come rimuovere ogni campata da un html:

public static String removeSpans(String html) { 
    Source source = new Source(html); 
    source.fullSequentialParse(); 
    OutputDocument outputDocument = new OutputDocument(source); 
    List<Tag> tags = source.getAllTags(); 
    for (Tag tag : tags) { 
     String tagname = tag.getName().toLowerCase(); 
     if (tagname.equals("span")) { 
      //remove the <span> 
      outputDocument.remove(tag); 
     } 
    } 
    return outputDocument.toString(); 
} 
+0

Ci scusiamo per il downvote, ma questa risposta non è pertinente alla mia domanda. –

0

Come altri hanno suggerito, probabilmente si desidera eseguire il rendering del DOM. Questo in pratica significa solo costruire l'albero dei nodi, non altererà la fonte del documento a meno che non si usi un pulitore HTML come jTidy. Quindi hai un facile accesso al documento e puoi modificarlo come richiesto. Suggerirei DOM4J, ha anche un buon supporto per api e xpath.

Re il tuo requisito di "indicizzazione", durante il traversamento/interrogazione del documento è possibile memorizzare in una cache in un elenco o mappare tutti gli elementi o nodi che si desidera modificare il testo di un punto successivo.

2

Sembra che Jericho sia esattamente quello che vuoi. Si tratta di un parser HTML robusto progettato specificamente per apportare modifiche non invadenti al documento sorgente.

Sebbene non sia dotato di interfacce DOM, SAX o StAX, ha API personalizzate che sono abbastanza simili a quegli standard che dovresti essere in grado di adattare il tuo approccio a loro abbastanza facilmente, o scrivere un adattatore tra qualsiasi cosa stai usando e Jericho. Ad esempio, puoi eseguire query XPath sui documenti Jericho usando Jaxen - vedi this blog entry per un esempio.

Jericho ha begin e termina gli attributi per ogni elemento, e anche per parti dell'elemento come il nome del tag o anche un nome di attributo, quindi puoi modificare il documento tu stesso con quell'informazione, ma dove Jericho brilla davvero è OutputDocument class, che consente di specificare direttamente le sostituzioni chiamando i metodi appropriati con gli elementi di Jericho che corrispondono alla query invece di dover richiamare esplicitamente getBegin() e getEnd() su di essi e passarlo a un metodo di sostituzione.

+0

Verificherò anche questo. Grazie. Tornerò e rispondo a ciascuno quando li ho provati. –

0

Questa grande opera

http://jtidy.sourceforge.net/

ESEMPIO

Tidy tidy = new Tidy(); // obtain a new Tidy instance 
tidy.setXHTML(boolean xhtml); // set desired config options using tidy setters 
...       // (equivalent to command line options) 

tidy.parse(inputStream, System.out); 

per la scansione del DOM, mi consiglia di utilizzare JDOM, il suo modo più veloce quindi semplice XML.

http://www.jdom.org/

DocumentBuilderFactory factory = 
DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
Document doc = builder.newDocument(); 
Element root = doc.createElement("root"); 
Text text = doc.createText("This is the root"); 
root.appendChild(text); 
doc.appendChild(root); 

Per quanto concerne l'attuazione vorrei fare un nuovo documento, e aggiungere nodi ad esso dalla sorgente.

1

Si utilizza jericho html parser per eseguire l'analisi e htmlcleaner per eseguire la pulizia vera e propria.

Abbiamo riscontrato problemi con il comportamento di jericho all'interno di un'app server (gestione della memoria, registrazione) risolti. (lo sviluppatore originale non pensava che i nostri problemi fossero abbastanza importanti da inserire il ramo del codice principale). Our fork is on github. Abbiamo anche effettuato fixes to htmlcleaner.

0

Si potrebbe provare ANTLR con un HTML grammar.

Si potrebbe prendere (almeno) 2 approcci - cercare di usarlo come un parser HTML vero e proprio, e quindi ottenere gli indici nella stringa originale che siete interessati a

Oppure, ha anche incorporato. in supporto per le trasformazioni sul posto sul testo di origine, dove si definiscono le trasformazioni che si desidera eseguire sul testo come parte della grammatica.

Problemi correlati