# xml jdom und jbuilder



## melmager (29. Dezember 2003)

Ich vermute mal das mein jbulder immer noch nicht die jdom Lib kennt 
ich bekomme sehr merkwürdige fehlermeldungen 

so sieht der code aus der grösste teil ist geklaut 

```
import java.io.*;  // neccessary for file handling
import java.util.*; // neccessary for container classes
import org.jdom.*;
import org.jdom.input.SAXBuilder;
public class impad {
  public static Document getDocument(String filename) {
    try {
      SAXBuilder builder = new SAXBuilder(true);
      return builder.build(new File(filename)); // return the parsed document
    }
    catch (JDOMException e) {
      System.out.println(e);
      System.exit(1);
    }
    return null; // is never reached
  }
  public static void main(String argv[])
  {
    //if (argv.length != 1){
    //  System.out.println("This program returns data");
    //  System.out.println("Usage: java Theatre2 <Play> ");
    //  System.exit(1);
    //}

    // create the jdom -  document
    Document doc = getDocument("2650.xml");
    // get access to the root element
    Element root = doc.getRootElement();
    System.out.println(GetName());
  }
}
```
und das ist der fehler:
Exception in thread "main" java.lang.NoClassDefFoundError: impad

liegt es am code oder doch an der jdom lib ? das jbulder die noch nicht kennt?


----------



## Christian Fein (29. Dezember 2003)

Die Fehlermeldung besagt er findet die Klasse
impad nicht.

Das hat nicht primär was mit JDOM zu tun, sondern 
du hast deine Klasse impad nicht gefunden was daran
liegen kann das das File der Klasse nicht impad.java 
heisst.

Zudem solltest du alle Klassenamen mit Grossem ersten
Buchstaben schreiben, das ist offizieller Java Stileguide.

Wie heisst die Datei in der impad liegt?


----------



## melmager (29. Dezember 2003)

häh ... 
mit andern Worten dasFile muss immer so heissen wie die Hauptklasse?

Ihhh warum steht das nirgens in den Büchern....

Aber nachdem ich das File umbenannt habe kommen wenigstens mehr Fehlermeldungen 

kann verzeichnis org.jdom nicht finden wie nett 

wieso Verzeichnis


----------



## Christian Fein (29. Dezember 2003)

> _Original geschrieben von melmager _
> *häh ...
> mit andern Worten dasFile muss immer so heissen wie die Hauptklasse?
> 
> ...



Weil die Klassen (innerhalb eines jar Files) immer den Verzeichnissen gepackt sind, wie sie in den Namespaces liegen.

Sprich die Klasse de.holyfly.Test 
liegt in
de/holyfly/ verzeichnis.

Das liegt dann schon daran das das Jar file nicht korrekt eingebunden worden ist.
Wie gesagt, JBuilder muss ich passen, unter eclipse kann ich dir das erklären.


----------



## melmager (30. Dezember 2003)

Also soweit ich die beschreibung von JDOM verstanden habe
muss nur ein Link zum jdom.jar vorhanden sein
ich habe das ding mal ich das verzeichnis von den anderen *.jar von Jbuilder 
reingeworfen - das wars leider auch nicht

Eclipse habe ich mir mal beide Versionen runtergeladen 
die motif und die gtk Version die angeblich nach dem readme beide auf mein
Suse 8.1 laufen sollen - pustekuchen

gtk vermisst eine libgtk_x11 die bei Suse nicht dabei ist
und die Motif-version haut mir ein Errorcode -1 um die Ohren

was ich jetzt noch nicht verstanden habe:

warum nennt sich das beim Include org.jdom
das file ist doch jdom.jar und nicht org.jar 
das org ist aber in jedem Beispiel zu sehen was ich bisher gelesen habe

da ja das File so heissen muss wie die Klasse verstehe ich jetzt nicht wo 
das org her kommt - ist warscheinlich Gottgegeben

import org.jdom.*;
ok hier scheint er die ganze classe einzufügen * steht normal für alles 
import org.jdom.input.SAXBuilder;
aber warum dann den speziell ? der muss doch schon da sein

Alles etwas merkwürdig und völlig undurchsichtig


----------



## Christian Fein (30. Dezember 2003)

> _Original geschrieben von melmager _
> *Also soweit ich die beschreibung von JDOM verstanden habe
> muss nur ein Link zum jdom.jar vorhanden sein
> ich habe das ding mal ich das verzeichnis von den anderen *.jar von Jbuilder
> ...


Wegen der libgtk_x11. 
Im zip File ist eine .so Datei, diese nach /usr/local/lib werfen ldconfig laufen lassen, sollte Problem beheben.

wegen org.jar
Weil es sich nicht um das importieren eines Jar files handelt sondern um den 
Import eines Namespaces. Und der namespace lautet org.jdom



> _Original geschrieben von melmager _
> *
> da ja das File so heissen muss wie die Klasse verstehe ich jetzt nicht wo
> das org her kommt - ist warscheinlich Gottgegeben
> ...



Siehe oben.



> _Original geschrieben von melmager _
> *
> ok hier scheint er die ganze classe einzufügen * steht normal für alles
> import org.jdom.input.SAXBuilder;
> ...



Nein nicht undurchsichtig, sondern logisch, sobald mann das konzept verstanden hat.
tiere.vierbeiner.*;
importiert alle enthaltenen Klassen
tiere.vierbeiner.Giraffe
tiere.vierbeiner.Elefant

Aber es importiert nur die Klassen, und nicht 
subnamespaces.


----------



## melmager (30. Dezember 2003)

ok nach dem ich noch ein link gesetzt habe findet mein Jbuilder meine JDOM Klasse 
also zwei links setzen einen für den Jbulder und ein ein fürs aktuelle Projekt 

jetzt mault er noch die zeile an:

return builder.build(new File(filename)); // return the parsed document

die ich so geklaut habe 

"impad.java": Fehler #: 360 : Nicht bekannte Exception java.io.IOException; muss abgefangen werden oder zum Auslsen deklariert werden in Zeile 9, Spalte 22

spalte 22 ist das mit build

Nachtrag zu Eclipse:



> Im zip File ist eine .so Datei, diese nach /usr/local/lib werfen ldconfig laufen lassen, sollte Problem beheben.



nee leider nicht vorhanden das file;  da muss ich wohl mal tante googel fragen - irgendeiner muss das Ding doch schon mal zum laufen bekommen haben


----------



## Christian Fein (30. Dezember 2003)

melmager hat gesagt.:
			
		

> ok nach dem ich noch ein link gesetzt habe findet mein Jbuilder meine JDOM Klasse
> also zwei links setzen einen für den Jbulder und ein ein fürs aktuelle Projekt
> 
> jetzt mault er noch die zeile an:
> ...



Kannst dich noch errinnern in dem Thread PHP Programmierstil, habe ich genau dies als grossen Vorteil von Java erleutert. 
Den muss, mögliche Ausnahmen abzufangen und zu behandeln.

Zur erklärung: die methode build(File) liest aus einer Datei ein Dokument und gibt 
ein Object der Klasse Document zurück.
Bei dieser Leseoperation können Fehler auftreten, obwohl der Code richtig ist. Z.b ist das File Korrupt und lässt sich nicht komplett lesen, oder es existiert kein Leserecht darauf usw.
Java zwingt dich nun dich mit diesem Problem zu beschäftigen.
Das heisst dir stehen jetzt 2 Wege offen: Du behandelst eine mögliche Ausnahme oder gibst sie an den Aufrufer weiter.
Das sieht folgendermassen aus:

Variante 1:

```
try {
  // etwas möglicherweise problematisches machen
} catch(Exception e) {
  // Ausnahme abfangen
} finally {
  // aufräumarbeiten durchführen.
}
```
Hierbei ist finally optional.

Variante 2:

```
public void aufrufer() {
  try {
      tuWasProblematisches();
  } catch (Expcetion e) {
     System.out.println("Dumm gelaufen, Fehler: e.getMessage());
  }
}
private void tuWasProblematisches() throws Exception {
 // etwas problematisches tun
}
```

In Variante 1 wird in einem try Block etwas problematisches versucht (try).
Beim Auftreten einer Ausnahme wird ein passender Catch block gesucht, der
die best passende Exception Klasse als Parameter aufweist. Sprich bei ioexception und 2 catchblöcken  
Beispiel:
try {
 // Dateioperation
} catch(IOException e) {
  // fehler io
} catch(SQLException e) {
  //fehler sql
}
wird die IOException angesprungen. Wenn kein passender Catch Block existiert, so wird nach Oberklasse der IOException gesucht, sprich z.b Exception. Wird auch das nicht gefunden so meldet der Compiler schon zur Kompilierzeit einen Fehler.

Variante 2 wirft die Exception einfach weiter zum Aufrufer, das dieser sich darum kümmern soll. Entweder wirft dieser Aufrufer (eine methode) diesen wiederrum weiter oder kümmert sich mit dem try {} catch {} darum.

Verständlich? Ansonsten: 
javabuch.de -> Ausnahmebehandlung

Also in deinem Beispiel:

```
try {
  return builder.build(new File(filename)); // return the parsed document
} catch(IOException e) {
  System.out.println("Fehler bei Leseoperation"+e.getMessage());
  System.out.prinln("Stacktrace\n"+e.printStackTrace());
}
```
Oder aber die Methode so umschreiben das 
public irgendwas einMethodenname() throws IOException {
}

Natürlich musst du auch diese Klasse IOException importieren.



			
				melmager hat gesagt.:
			
		

> nee leider nicht vorhanden das file;  da muss ich wohl mal tante googel fragen - irgendeiner muss das Ding doch schon mal zum laufen bekommen haben


Ja ich habe es z.b zum laufen bekommen, motif und gtk version


----------



## melmager (30. Dezember 2003)

Stand Eclipse installation:

Habe festgestell das ich gtk2 brauche aber um das in Sytem einzubauen brauche ich wieder
jede Menge andre Libs - das würde zu einer Installationsorgie führen.
so wies aussieht brauche ich minimum Suse 8.2 mal sehen ob ich die mal runtersauge 
aber selbst wenn - Es scheint  dann noch ein paar Sprachprobleme oder Zeichensatzprobleme bei Suse mit Eclipse zu geben :-(

Ich finds nur lustig das der Code aus einem Beispielcode stammt - und nachdem was ich
nun weiss nie so gelaufen ist.

Schimpfmodus on:
Das nenne ich doch Einführung in eine Sprache - ich mache ein Democode der nicht
gehen kann und der Einsteiger darf sich damit rumägern.
Damit lernt er erst mal was alles nicht geht und freut sich über Kleinigkeiten die gehen 
Nach dem Motto:
Fahrlehrer zum Schüler: Da es ihre erste Fahrstunde ist üben wir mal rückwärts einparken an einer steilen Strasse ...
Schimpfmodus off

 Nein java du bekommst mich nicht klein  
Dann kann ich demächst wenigstens auf höheren Level lästern *g*

aber Zurück zum Thema:

try {
  return builder.build(new File(filename)); // return the parsed document
} catch(IOException e) {
  System.out.println("Fehler bei Leseoperation"+e.getMessage());
  System.out.prinln("Stacktrace\n"+e.printStackTrace());
  Sxstem.exit(1);
} catch (JDOMException e) {
      System.out.println(e);
      System.exit(1);
}

die Richung ? für beide Fehler möglichkeiten ?

So So - dann kann der ja auch nicht gehen 
http://www.tutorials.de/forum/showthread.php?threadid=66060

Nicht hauen - duck *g*



> Kannst dich noch errinnern in dem Thread PHP Programmierstil, habe ich genau dies als grossen Vorteil von Java erleutert.



Klar kann ich das  der Thread ist die wahrgemache Drohung das ich meine Problem hier abladen werde -
smile


----------



## Christian Fein (30. Dezember 2003)

melmager hat gesagt.:
			
		

> Stand Eclipse installation:
> 
> Habe festgestell das ich gtk2 brauche aber um das in Sytem einzubauen brauche ich wieder
> jede Menge andre Libs - das würde zu einer Installationsorgie führen.
> ...



Jetzt muss ich mal zurückschimpfen.
JDOM ist ein Zusatzmodul zur Sprache. Ist nicht dafür gedacht grundlegende Kentnisse in Java zu erhalten. Um diese zu erhalten beschäftigt mann sich mit 
den Grundlagen bis mann diese beherrscht und widmet sich dann tiefergehende 
Funktionaltäten. 
Wer kein PHP kann, sollte auch nicht gleich versuchen mit PEAR zu arbeiten.



			
				melmager hat gesagt.:
			
		

> Nein java du bekommst mich nicht klein
> Dann kann ich demächst wenigstens auf höheren Level lästern *g*
> 
> aber Zurück zum Thema:
> ...



Ist ja auch kein Problem, dennoch solltest du dich mit den Grundlagen beschäftigen, dinge wie Namespaces und Exceptions gehören dazu 

Zu dem Codebespiel:
Weiss nicht ob der jetzt lauffähig ist, denn die Methode hat einen kleinen Fehler.
Sie liefert unter Umständen keine Rückgabe.
Ob der Compiler nicht meckert da die ganze Applikation beim auftreten eines Fehlers beendet wird, weiss ich jetzt nicht. Falls ja dann setze noch jeweils ein
return null; dazu. Ansonsten ist dies korrekt. Wobei ich aufgrund besseren 
Codestil das Beispiel folgendermassen umschreiben würde:

```
.....
try {
  Document tmp =  builder.build(new File(filename)); // return the parsed document
} catch(IOException e) {
  System.out.println("Fehler bei Leseoperation"+e.getMessage());
  System.out.prinln("Stacktrace\n"+e.printStackTrace());
  Sxstem.exit(1);
} catch (JDOMException e) {
      System.out.println(e);
      System.exit(1);
} 
  return tmp;
}
```

grüsse


----------



## melmager (30. Dezember 2003)

so kurze Zwischenmeldung:

Ich habe Eclipse am laufen unter Suse 8.1.  (die gtk Variante - Motif stürzt immer noch ab)
Ich habe eine gtk2 Version gefunden die geht
Das ich auch gleichzeitig Gimp installiert habe hat dann deutlich weitergeholfen 

In der Personal Edition von Jbuilder kann man nachträglich JDOM einfügen 

Zwei Links setzen:
Projekteigenschaften dort benötigte Bibliotheken JDOM hinzufügen
und
unter tools/ bibliotheken konfigurieren
einen verweis auf JDOM setzen

und danke an Chris hier habe ich mehr über Namensraum konvetionen mitbekommen wie
im Buch steht - die haben das Thema gekonnt ausgelassen 

So mal sehen ob ich es jetzt hinbekomme das eigendliche Problem zu lösen:

Eine XML Datei einlesen und dann damit mein Programm zu steuern 

Ich glaub nicht das das alles war  
aber erstmal noch ein wenig stöbern in Buch und Democodes


----------



## melmager (25. Januar 2004)

Nach längerer Pause mal wieder Java :-(


Ich brache mal ein JDOM Beispiel was geht ich bekomme es nicht zum laufen ein
XML einzulesen :-(

der Fehler:

org.jdom.input.JDOMParseException: Error on line 2 of document file:/home/wolfgang/jbproject/impad/test.xml: Document is invalid: no grammar found.

Das ist die XML Datei:

<?xml version="1.0"?>
<impad>
<main>
testeintrag
</main>
</impad>

```
// create the jdom -  document
    Document doc = getDocument("test.xml");
    // get access to the root element
    Element root = doc.getRootElement();
    // Element haupt = root.getChild("main");
```
das sind die entscheiden Java Zeilen


----------



## Christian Fein (26. Januar 2004)

> _Original geschrieben von melmager _
> *Nach längerer Pause mal wieder Java :-(
> 
> 
> ...



Du musst dir das Dokument erst zusammenbauen, das geschieht durch den SAX Builder.


```
import org.jdom.*;
import org.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
// Klassendeklaration usw ausgelassen

SAXBuilder sxbuild 
     = new SAXBuilder();
InputSourc is 
     = new InputSource(path);
Document doc = sxbuild.build(is);
Element root = doc.getRootElement();
```
path ist hierbei z.b 
path = "/home/chris/docs/test.xml";
path =  "c:\java\projekte\jdomproj\test.xml"

oder bzw im verhältnis zur Application
xmlfiles/test.xml.

Sprich Document doc wird lesenderweise nicht einfiach instanziert sondern mann
erhält dieses Dokument durch einen SAXBuilder. Grund:
Lesender zugriff auf ein XML Dokument geht eindeutig am schnellsten per SAX.

Ich habe dazu ein (zugegebenermassen sehr kleines)Tutorial geschrieben:
braucht ein InputSource und kein File direkt. Die InputSource wird  durch


----------



## melmager (26. Januar 2004)

@Christian hatte es eilig  weil er mitten im Satz aufhört -



> Du musst dir das Dokument erst zusammenbauen, das geschieht durch den SAX Builder.



mache ich doch  in meiner Classe Document ...

und ich muss JDOM nutzen da kommt ja noch mehr  ausserdem schein
Jdom einfacher zu sein wie Sax allein. Wenn ich mir die Beispiele so ansehe.

Die Klasse Document gibst weiter oben im Thread zu bewundern 

Den Fehler macht er immer noch - nur kein Plan warum 
die Syntax vom XML ist doch richtig warum mault er die an?

Nachtrag:
Kann es sein das bei JDOM das XML File valid sein muss ?


----------



## Christian Fein (27. Januar 2004)

> _Original geschrieben von melmager _
> *@Christian hatte es eilig  weil er mitten im Satz aufhört -
> 
> 
> ...



Das File muss nur wohlgeformt sein.

```
private Document getDocument(AddTutorialSiteForm form) throws 
       JDOMException, IOException {
                SAXBuilder builder = new SAXBuilder();
                Document doc = new Document();
                String a = "<root>"+form.getText()+"</root>";
                StringReader reader = new StringReader(a);
                doc = builder.build(reader);
                XMLOutputter outputter = new XMLOutputter(" ",true);
                outputter.output(doc,System.out);
                return doc;
        }
```

Dieser code ist i.o, da ich ihn gerade selber in einem Projekt nutze.
form.getText() gibt valid XHTML aus, und packt das in ein Root Element.
Dann wird ein StringReader genutzt um den String zu verpacken, weil
der SAXBuilder gerne einen Reader haben will. 
Mit einem Writer deiner Wahl, an einen XMLOutputter übergeben, kann der ganze "Scheiss" wieder ausgegeben werden.


----------

