# Auf der Suche nach einem HTML / CSS Parser



## Prophet05 (15. Dezember 2007)

Moin,

ich habe mich mal nach einem XML / HTML / CSS Parser umgeschaut. Einen XML Parser gibt es ja bereits in der Standard Bibliothek. Bei der Suche nach HTML Parsern bin ich über allerlei gestolpert und meine Suche nach einem CSS Parser ist fast gescheitert.

Nun wollte ich euch mal Fragen ob ihr gute HTML & CSS Parser kennt? HTML Parser gibt es ja viele aber wie viele unterstützen den DOM standard des W3C oder können vielleicht sogar das HTML Rendern das sie Parsen. Mir ist es schon oft unter gekommen das die Parser komplett ihre eigenen Interfaces mitgeliefert haben obwohl die Standard Bibliothek ja bereits ein DOM Kompatibles set interfaces liefert.

Beim CSS Parser habe ich zufällig entdeckt das das Packet org.w3c.dom.css Exsistiert, allerdings ohne in der Dokumentation aufzutauchen oder einen Parser mitzuliefern. Ausserdem bietet das W3C nochmal zusätzlich eine Schittstelle "SAC" an, aber wieder ohne Parser. Und dann habe ich auch noch das dieses Projekt gefunden, welches zwar ein DOM und ein SAC interface bietet aber scheinbar noch im Beta stadium befindlich ist.

Welche Parser könnt ihr mir empfehlen? Kennt ihr vielleicht sogar Projekte die HTML und CSS rendern können und *einfach* in eine Java-Anwendung zu integrieren sind?

Ich habe mir auch mal Mozilla angeschaut, aber dort finde ich weder anfang noch ende, geschweige den ein gescheites Java-Binding...

Gruß, Prophet05


----------



## Klein0r (3. September 2008)

Ohne ein neues Thema aufmachen zu wollen.
Ich stehe jetz vor dem selben Problem.

Hoffe irgendjemand weiß Rat wenn du nichts gefunden hast 

Teste aber dennoch erstmal den von dir angegebenen Link (Scheint als wenn es 3 Monat nach deinem Post noch Sources gab) 
http://sourceforge.net/projects/cssparser/

Zu html-Parser hab ich folgendes gefunden:
http://java.sun.com/products/jfc/tsc/articles/bookmarks/index.html

lg


----------



## Thomas Darimont (3. September 2008)

Hallo,

schau mal hier:
http://java-source.net/open-source/html-parsers
https://jxcss.dev.java.net/

Gruß Tom


----------



## Klein0r (3. September 2008)

Probiere gerade mit jxcss rum - werde aber absolut nicht schlau draus...

Glaube ich verstehe grundsätzlich die Parser falsch.
Ich bekomme keine 3 Zeilen auf die Reihe!

Batik 1.7 Steady State 0.9.5 und Flute 1.3 hatte ich auch schon - aber ich kann damit einfach nichts anfangen - glaube ich bin wirklich zu doof dafür! Kann mir jemand einen Ansatz nennen was ich machen muss? Bzw was für Schritte?

Muss ich mir eine Klasse schreiben die ein ganz bestimmtes Interface implementiert?
Ich möchte einfach nur ein bestehendes CSS-File parsen und alle Elemente auflisten - das reicht mir schon... Ich bin wirklich zu doof glaube ich...

lg


----------



## Prophet05 (4. September 2008)

Also bei jxcss steht doch sogar ein Beispiel auf der Hauptseite:
https://jxcss.dev.java.net/

Beim HTML Parser von Swing wäre ich mir aufgrund des Alters unsicher inwiefern man den Heute noch an komplexere Seiten ran lassen darf. 

Ansonsten nochmal danke für den Link auf die Java-Source Seite. Gibt es zu der dort präsentierten Auswahl noch Erfahrungswerte oder Empfehlungen?

Gruß, Prophet05


----------



## Spechter (4. September 2008)

Prophet05 hat gesagt.:


> HTML Parser gibt es ja viele aber wie viele unterstützen den DOM standard des W3C oder können vielleicht sogar das *HTML Rendern *das sie Parsen.


Wenn du HTML/CSS rendern möchtest dann würde ich dir https://xhtmlrenderer.dev.java.net/index.html empfehlen. Das benütze ich um z.B. aus HTML-Seiten eine PDF-Datei zu erstellen


----------



## Klein0r (4. September 2008)

Prophet05 hat gesagt.:


> Also bei jxcss steht doch sogar ein Beispiel auf der Hauptseite:
> https://jxcss.dev.java.net/



Das stimmt wohl - aber das geht so nicht weil man den Kommentar durch Quelltext ersetzen sollte:

```
// Initialize the parser factory and the content handler
```

Nur genau da weiß ich nicht wie man an 2 Instanzen kommen soll!
Keine Ahnung...

Ich hab schon viel probiert - wenn ich zu Haus bin kann ich ja mal meinen aktuellen Stand posten. Gestern abend hatte ich einfach keine Lust mehr da weiter zu machen! Aber wenn jetzt schon jemand weiß wie das geht: Her damit! 

Bis später

lg


----------



## Prophet05 (5. September 2008)

Klein0r hat gesagt.:
			
		

> Nur genau da weiß ich nicht wie man an 2 Instanzen kommen soll!
> Keine Ahnung...


Ohne mich jetzt genauer damit beschäftigt zu haben würde ich behaupten das du diese Instanzen bei dem von dir gewählten Parser holen musst. Da muss es irgendwo eine Klasse geben die die entsprechenden Interfaces implementiert oder eine Factory die dir Entsprechendes rauswirft.



			
				Spechter hat gesagt.:
			
		

> Wenn du HTML/CSS rendern möchtest dann würde ich dir https://xhtmlrenderer.dev.java.net/index.html empfehlen. Das benütze ich um z.B. aus HTML-Seiten eine PDF-Datei zu erstellen


Danke den kannte ich noch nicht!


----------



## Klein0r (5. September 2008)

Prophet05 hat gesagt.:


> Ohne mich jetzt genauer damit beschäftigt zu haben würde ich behaupten das du diese Instanzen bei dem von dir gewählten Parser holen musst. Da muss es irgendwo eine Klasse geben die die entsprechenden Interfaces implementiert oder eine Factory die dir Entsprechendes rauswirft.



Ja es gibt sowas wie newParser oder makeParser. Bin mir gerade nichtmehr so sicher. Werde mich da erst am Wochenende wieder mit auseinander setzen können. Also morgen oder übermorgen!

Dann werde ich da hoffentlich schlau draus.
Ich hab mir mit den XML-Parsern ja auch schon einen abgebrochen... Aber das ist so lange her das ich den Ansatz da nichtmehr kenne und die sources auch nicht finde - doof gelaufen! Aber da war es nen ähnliches hin und her...
Muss mal meine Unterlagen durchwühlen.

lg


----------



## Klein0r (6. September 2008)

So folgendes.

So weit bin ich gekommen:

```
import java.io.IOException;

import jxcss.SAXCSSDocumentHandler;

import org.w3c.css.sac.CSSException;
import org.w3c.css.sac.InputSource;
import org.w3c.css.sac.Parser;
import org.w3c.css.sac.helpers.ParserFactory;
import org.xml.sax.ContentHandler;

public class ParserMain {

	public static void main(String[] args) {

		ParserFactory parserFactory = new ParserFactory();
		Parser parser  = null;
		ContentHandler contentHandler = null;
		SAXCSSDocumentHandler documentHandler = null;
		
		try {
			
			parser = parserFactory.makeParser();
			
			//documentHandler = new SAXCSSDocumentHandler(contentHandler);
			parser.setDocumentHandler(documentHandler);
			
			parser.parseStyleSheet(new InputSource("stylesheet.css"));
			
		} catch (CSSException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			e.printStackTrace();
		} catch (ClassCastException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}

	}
}
```

Verstehe das nich so ganz warum ich ne NullPointerException bekomme...
Gibt doch von allem Instanzen.

```
java.lang.NullPointerException: No value for sac.parser property
	at org.w3c.css.sac.helpers.ParserFactory.makeParser(ParserFactory.java:35)
	at stillinuse.ParserMain.main(ParserMain.java:24)
```

Zeile 24 ist:

```
parser = parserFactory.makeParser();
```

Weiß jemand Rat?


----------



## Klein0r (6. September 2008)

So irgendwie bekomme ich keinen SAC-Parser hin.
Wenn ich das habe dann gehts glaube ich gut vorran.

Ich habe mal den Sourcecode zur vorher genannten Exception gesucht:

```
/*
 * Copyright (c) 1999 World Wide Web Consortium,
 * (Massachusetts Institute of Technology, Institut National de
 * Recherche en Informatique et en Automatique, Keio University). All
 * Rights Reserved. This program is distributed under the W3C's Software
 * Intellectual Property License. This program is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.
 * See W3C License http://www.w3.org/Consortium/Legal/ for more details.
 *
 * $Id: ParserFactory.java,v 1.1 2000/02/14 15:54:49 plehegar Exp $
 */
package org.w3c.css.sac.helpers;

import org.w3c.css.sac.Parser;

/**
 * @version $Revision: 1.1 $
 * @author  Philippe Le Hegaret
 */
public class ParserFactory {
    
    /**
     * Create a parser with given selectors factory and conditions factory.
     */    
    public Parser makeParser()
	throws ClassNotFoundException,
	       IllegalAccessException, 
	       InstantiationException,
 	       NullPointerException,
	       ClassCastException {
	String className = System.getProperty("org.w3c.css.sac.parser");
	if (className == null) {
	    throw new NullPointerException("No value for sac.parser property");
	} else {
	    return (Parser)(Class.forName(className).newInstance());
	}
    }
}
```

Nur was bitte macht System.getProperty("org.w3c.css.sac.parser"); ?
Was wird da geladen und wie kann ich so an ein Ergebnis kommen?

Ich raffs nich 

danke

*EDIT:*
So ich habe es endlich hinbekommen - war eigentlich sehr einfach. Allerdings ohne diese jxcss-Geschichte:


Batik laden: http://xmlgraphics.apache.org/batik/
SAC laden: http://www.w3.org/Style/CSS/SAC/
folgende Libs einbinden:
sac.jar
batik-css.jar
batik-util.jar


Nun funktioniert das ganze folgendermaßen:

```
import java.io.FileReader;
import java.io.IOException;

import org.apache.batik.css.parser.Parser;
import org.w3c.css.sac.CSSException;
import org.w3c.css.sac.InputSource;

public class ParserMain {

	public static void main(String[] args) {
		
		Parser p = null;
		FileReader cssReader = null;
		MyCssDocumentHandler cssDocHandle = new MyCssDocumentHandler();
		
		try {
			p = new Parser();
			cssReader = new FileReader("test.css");
			
			p.setDocumentHandler(cssDocHandle);
			p.parseStyleSheet(new InputSource(cssReader));
			
		} catch (CSSException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}
```

Die Klasse MyCssDocumentHandler habe ich natürlich selbst geschrieben.
Sie implementiert das Interface: import org.w3c.css.sac.DocumentHandler

Nun knallt man alle Methoden rein und schon kanns losgehen 

Eigentlich einfacher als man denkt. Aber ich habe einfach den ganzen Krams
total verrafft. Naja nun läufts. Mein Problem war das ich das abhängige lib
batik-util.jar nicht mit eingebunden haben - so gabs etliche exceptions mit
denen ich nix anfangen konnte.

Danke für die Hilfe!

lg


----------

