# Html/XML mit XPath auslesen in Java



## basmati123 (12. Mai 2008)

Hallo,

ich hoffe, ich bin hier im richtigen Forum.

Ich versuche derzeit einen Html-Quelltext in einen Xml-Quelltext umzuwandeln und ihn dann auszulesen - mit Xpath.
Leider habe ich sehr wenig Ahnung von Xml.

Hier wandel ich den Html-Quelltext in Xml um (hoffe ich wenigstens)
quelltext ist der InputStream, der den Html-Quelltext enthält


```
public void umwandeln() {

		org.cyberneko.html.parsers.DOMParser parser = 
			new org.cyberneko.html.parsers.DOMParser(); 

		try {	
			parser.parse( new InputSource(quelltext) );
		}
		catch (Exception e){
			System.out.println(e.getMessage());
		}

		// Um XML-Dokument als JDOM-Document weiterzuverarbeiten, 
		// DOMBuilder nutzen:
		DOMBuilder builder = new DOMBuilder(null);
		org.jdom.Document document = builder.build( parser.getDocument() );
		
		// Ausgabe des quelltextes in xml-form
		try {
			new XMLOutputter().output(document, System.out);
		} catch (IOException e) {
		
			e.printStackTrace();
		}

                // Objekt der Klasse XmlHTMLInterpretation erzeugen und ihr das            //xml-dokument übergeben, um es in der Klasse zu interpretieren/auszulesen

		XmlHTMLInterpretation interpret = new XmlHTMLInterpretation(document);
		
	}
```
 
Ich hoffe, ich habe nur das notwendige gemacht und nicht etwa etwas überflüssiges? 

die klasse des erstellen objekts unten, dass das xml-dokument übergeben bekommt, sieht folgendermaßen aus:


```
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.jdom.Document;

public class XmlHTMLInterpretation {

	Document document;
	XPath xpath;
	
	XmlHTMLInterpretation(Document document){
		this.document = document;
		this.xpath = XPathFactory.newInstance().newXPath();

// Hier versuche ich irgendwie den Titel herauszubekommen - war nur rumprobiererei
		String titel = getEinzelInhalt("/wurzel/head/title");
		System.out.println(titel);
		titel = getEinzelInhalt("/@title");
		System.out.println(titel);
	}

	
	public String getEinzelInhalt(String p) {
		String ergebnis = null;
		try {
			ergebnis = xpath.evaluate(p, document);
			System.out.println(ergebnis);
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		return ergebnis;
	}
}
```

Ich versuche also zur Zeit den Titel aus dem HTML-Quelltext auszulesen, aber ich verstehe irgendwie nicht (auch nach mehrmaligem Nachlesen), wie ich das genau anstellen soll - sind meine Ansätze richtig?
Kann mir jemand einen Tipp geben?
Für Hilfe wäre ich sehr dankbar.

Mit freundlichen Grüßen,
basmati123


----------



## zerix (14. Mai 2008)

Hallo,

was genau funktioniert denn nicht?

MFG

Sascha


----------



## basmati123 (14. Mai 2008)

Hallo,

Zur Zeit versuche ich mit dem geposteten Code eben den Titel eines Quelltextes(xml) auszulesen (also <title>xyz</title>), aber ich kriege keine Rückgabe, nur null (String ergebnis = null; für den Fall, dass nichts ausgelesen werden kann) und verstehe leider nicht, was ich falsch mache!

Für einen Tipp wäre ich dankbar!


----------



## zerix (14. Mai 2008)

Hier hab ich es mal getestet. Das ganze aber ohne JDom


```
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;

public class XmlHTMLInterpretation {

  Document document;
  XPath xpath;
  
  XmlHTMLInterpretation(Document document){
    this.document = document;
    this.xpath = XPathFactory.newInstance().newXPath();
// Hier versuche ich irgendwie den Titel herauszubekommen - war nur rumprobiererei
    String titel = getEinzelInhalt("/HTML/HEAD/TITLE");
    System.out.println("1. "+titel);
  }

  
  public String getEinzelInhalt(String p) {
    String ergebnis = null;
    try {
      ergebnis = xpath.evaluate(p, document);
      System.out.println(ergebnis);
      
    } catch (Exception e) {
      e.printStackTrace();
    }
    return ergebnis;
  }
}
```


```
import java.io.FileInputStream;

import org.cyberneko.html.parsers.DOMParser;
import org.xml.sax.InputSource;



public class XmlHtmltest
{

  public static void main(String[] args)
  {
    DOMParser parser = new DOMParser();
    try
    {
      
      parser.parse(new InputSource(new FileInputStream("test.html")));
      
        
      XmlHTMLInterpretation interpretation = new XmlHTMLInterpretation(parser.getDocument());
    }
    catch (Exception e)
    {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    
    
  }
  
}
```



```
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Insert title here</title>
</head>
<body>

</body>
</html>
```

Ausgabe


> Insert title here
> 1. Insert title here



MFG

Sascha


----------



## basmati123 (14. Mai 2008)

vielen Dank

der Fehler war also anscheinend das Document (org.w3c.dom.Document!)
Auf jeden Fall klappt es jetzt soweit! Danke!!

mfg,

basmati123


----------



## basmati123 (15. Mai 2008)

Noch eine Frage:

Wie mache ich das jetzt, wenn ich alle auslesen will, die da sind, nicht nur eins?

Also beispielsweise mit <h2> - sind in dem Quelltext mehrere <h2> dann liest er mit der erstellten Methode nur das erste <h2> aus, aber natürlich nicht die anderen..

Ich habe schon nachgelesen, aber ich finde die Lösung einfach nicht - habe das mit selectNodes, etc, probiert, aber das scheint nicht zu passen - liegt das daran, dass jetzt der DOMBuilder weg ist? Oder was mach ich falsch?

(List items = document.selectNodes(String p))

Da steht, die Methode ist undefiniert für den Typ Document - überall, wo ich nachlese, finde ich, dass man ein DOM-Dokument übergeben soll? Mein org.w3c.dom.Document document passt also nicht? Was mache ich jetzt? Ich kann doch nicht schon wieder alles ändern?

Wäre toll, wenn mir nochmal jemand helfen könnte!

Danke!


----------



## zerix (16. Mai 2008)

Was möchtest du genau tun?

Ich hab verstanden, dass du an alle Tags einer Sorte möchtest, aber nicht was du machen möchtest. 
Möchtest du mit XPath daran oder was möchtest du?

MFG

Sascha


----------



## basmati123 (16. Mai 2008)

Hallo,

ja, ich wollte mit xpath daran (auch weil ich annahm, dass es eine einfache (oder auch die einfachste) methode ist)

Ich möchte gerne beispielsweise den Inhalt aus allen <h2>xxx</h2> auslesen (also das xxx) - aber eben aus allen tags, die in dem quelltext sind, nicht nur aus einem

oder ich möchte alle <img src="xxxx"> oder alle <a href="xxx"> oder <meta name=y content =x> auslesen - also entweder das, was zwischen den tags steht oder das, was in den tags steht, aber ich möchte eben _alle_ kriegen und nicht nur den ersten

Ich möchte halt den Inhalt gerne in ArrayList<String> oder etwas ähnlichem (zB diesen Listen, wenn es funktionieren würde) dann sammeln

ich habe mich auch schon etwas mit xpath beschäftigt und denke, dass ich die ausdrücke, für das jeweilige, was ich haben will, schon hinbekomme, ich hänge momentan nur daran, _mehrere_ sachen herauszubekommen statt einem, weil das mit dieser "list" irgendwie nicht funktioniert

xpath wollte ich gerne nehmen, weil ich nicht tausend verschiedene sachen machen wollte um jedes einzelne auszulesen - ich wollte das halt alles mit xpath schaffen, damit es auch übersichtlicher für mich selber ist

sorry, ich bin leider noch anfänger auf dem gebiet

vielen dank! und mit freundlichen grüßen,

basmati123


----------



## basmati123 (18. Mai 2008)

also, selectNodes() funktioniert definitiv nicht bei einem org.w3c.dom Document, sondern (nur) bei org.dom4j.Document,
ein umwandeln in das erwähnte Document funktioniert aber nicht

Ich weiss wirklich nicht, wie ich ohne selectNodes an die ganzen Inhalte kommen soll - und für ein org.dom4j.Document müsste ich auch das ganze Erzeugen (von html in xml) ändern, oder nicht? 
Dann wäre ja alles bis jetzt umsonst?

Ich bräuchte wirklich Hilfe!
Vielen Dank und sorry - bin eben erst Anfänger!

basmati123


----------



## Adrian_Broher (19. Mai 2008)

Wie wär es wenn du mal die API von org.w3c.dom.Document und von javax.xml.xpath liest?


```
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(new File("./document.html"));

XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "//h2";
NodeList nodes = (NodeList) xpath.evaluate(expression, document, XPathConstants.NODESET);

for(int curNode = 0; curNode < nodes.getLength(); curNode++) {
    System.out.println(nodes.item(curNode));
}
```


----------



## basmati123 (19. Mai 2008)

Danke für die Hilfe - momentan funktioniert der Code so umgestellt zwar immer noch nicht, aber evtl. bekomme ich es ja noch hin..

ich habe es auch nochmal selber anders probiert:


```
String p = "H2";
NodeList items = document.getElementsByTagName(p);

System.out.println(h2.getLength());
for (int i= 0; i < items.getLength(); i++) {
	System.out.println(items.item(i));
}
```

Ausgabe:

```
4
[H2: null]
[H2: null]
[H2: null]
[H2: null]
```

Hilfe!
4 ist schon richtig - es sind 4 h2-tags in dem text, an dem ich teste - aber ich will doch das, was dazwischen steht (<h2>xxx</h2>) - wieso komme ich mit der methode nicht daran?


----------

