# FileStream auf Document



## niko022 (11. Okt 2005)

Hallo, 

ich habe ein Problemmit einem xml-File. 

Habe ein xml das ich bis jetzt über  



```
Document doc = getDocument(Resources/File.xml);
```


in mein Programm eingelesen habe. Wollte aber jetzt ein jar-File aus den gesamten Java-Files, die ich geschrieben habe, erstellen mit
Ressourcen.

Wenn ich jetzt aber Ressources/File.xml mit in das jar - File einpacke findet er die Datei nicht mehr. 

Habe versucht irgendwie das ganze mit 



```
InputStream stream = this.getClass().getResourceAsStream("Resources/File.xml");
```


einzulesen. Aber wie bringt man dann den InputStream stream wieder in ein Document doc. Bis jetzt habe ich das ganze
mit 


```
Element root = doc.getDocumentElement();
```


ausgelesen und weiterverarbeitet.

Gibt es vielleicht eine andere Möglichkeit ein xml einzulesen das mit in ein jar - File eingepackt ist. 

Vielen Dank


----------



## clemson (11. Okt 2005)

ich nehme mal an, du verwendest JDOM...

dann kannst du mittels

```
InputStream stream = this.getClass().getResourceAsStream("Resources/File.xml");

SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(stream);
```
ein Document aus diesem InputStream einlesen...

Oder hab ich da deine Frage falsch verstanden?


----------



## niko022 (11. Okt 2005)

Hallo,
ich verwende von w3c das Document Paket. 


```
import org.w3c.dom.Document;
```

Mal schauen vielleicht kann ich es auf jdom umschreiben oder beide mischen

Vielen Dank ich probier es gleich.


----------



## Bleiglanz (11. Okt 2005)

javax.xml.parsers.DocumentBuilder#parse

nimmt einen InputStream


----------



## niko022 (11. Okt 2005)

Wie funktioniert das genau?


----------



## Bleiglanz (11. Okt 2005)

```
Document doc = DocumentBuilderFactory.newDocumentBuilder().parse(this.getClass().getResourceAsStream("Resources/File.xml"))
```
oder so ähnlich


----------



## niko022 (11. Okt 2005)

Funktioniert irgendwie nicht ganz hat bei mir Probleme mit dem 

DocumentBuilderFactory.newDocumentBuilder()

static reference auf non static Methode. Wie bringe ich die new DocumentBuilder()
Methode auf static.


----------



## Bleiglanz (11. Okt 2005)

oops, soory

```
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(this.getClass().getResourceAsStream("Resources/File.xml"))
```
mieser Code, man soll nicht soviele Aufrufe verketten


----------



## niko022 (11. Okt 2005)

Cool einlesen funktioniert. Habe aber jetzt ein Problem mit der dtd. 

Relative URI "File.dtd"; kann nicht ohne eine Basis-URI aufgelöst werden

Jetzt parst er mir die File.xml nicht mehr. Er ließt sie ein, aber verarbeitet sie
nicht weiter, weil im die dtd irgendwie fehlt. 

Was kann ich da noch machen?

Vielen Dank nochmal


----------



## Bleiglanz (11. Okt 2005)

auf der Factory 

DocumentBuilderFactory#setValidating(false)

aufrufen, bevor du newDocumentBuilder machst

oder du schmeisst die DTD einfach raus, das mit dem Laden der DTD aus dem jar heraus ist etwas delikat...


----------



## niko022 (11. Okt 2005)

Ist ein bischen schwer die DTD rauszuschmeisen. Brauche sie zum Auflösen
beim Einlesen der xml.

Wie funktioniert das mit dem DocumentBuilderFactory? 

Hast du da irgendwas?


----------



## Bleiglanz (11. Okt 2005)

du brauchst die dtd doch unbedingt?

=> wo liegt sie denn? auch im jar??


----------



## niko022 (11. Okt 2005)

Ja ich packe es mit ein. Habe ein Verzeichnis Resources in dem sich das File.xml und File.dtd befindet.


----------



## Bleiglanz (11. Okt 2005)

kannst auf ein Schema umsteigen??

-> dann gäbs DocumentBuilderFactory#setSchema

mit einer DTD ist das ziemlich schwierig und erfordert echtes Parser gefrickel...


----------



## niko022 (11. Okt 2005)

Shit. Kenn mich mit dem ganzen auch nicht so tiefgehend aus.

Also müßte ich die dtd Datei immer zum jar File führen. Wollte eine Datei wo 
alles vereint ist (jar) sozusagen Ressourcen mit Java. 

Ich benötige die dtd um das ganze sauber zu parsen. Gibt an was für 
Elemente in dem xml bzw. Unterelementen es gibt.

Ohne das dtd kann ich es schlecht im Quellcode weiterverarbeiten. Findet 
dann die ganzen Elemente nicht. 

Hast du evtl. irgendwie ein Beispiel oder eine Beschreibung wie so was 
funktioniert.


----------



## Bleiglanz (11. Okt 2005)

>>Ich benötige die dtd um das ganze sauber zu parsen.

Nein, die ist nur zum überprüfen da; du kannst auch ohne DTD glücklich werden

Wenn du keine externen Entities in der DTD definierst, dann kannst du ohne weiteres drauf verzichen

1) prüfe dein xml gegen die DTD
2) wenn gültig, entferne den Doctype und stecks in das jar


----------



## niko022 (12. Okt 2005)

Hallo hatte gestern leider keine Zeit mehr zurückzuschreiben.

Habe unten mal den Aufbau der xml und der dtd angehängt.

Wenn ich die dtd weglassen kann ich die Wert aus der 
xml nicht lesen. Kann sie irgendwie beim einlesen und
zerlegen in Java nicht zuordnen. Findet dann nichts 

Habe ich die dtd funktioniert es.



```
<Variable>

    <Name> ..... </Name>
    <Help> ..... </Help>

    <Value default="true" >
      <Valuename> ..... </Valuename>
      <Valuehelp> ..... </Valuehelp>
      <Editable>false</Editable>
    </Value>

    <Value default="false" >
      <Valuename> ..... </Valuename>
      <Valuehelp> ..... </Valuehelp>
      <Editable>false</Editable>
    </Value>

  </Variable>
```



```
<?xml version = '1.0' encoding = 'iso-8859-1'?>
<!ELEMENT OwnConfig (Variable*)>
<!ELEMENT Variable (Name, Help, Value*)>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Help (#PCDATA)>
<!ELEMENT Value (Valuename, Valuehelp, Editable)>
<!ATTLIST Value default CDATA #REQUIRED>
<!ELEMENT Valuename (#PCDATA)>
<!ELEMENT Valuehelp (#PCDATA)>
<!ELEMENT Editable (#PCDATA)>
```



Das parsen mache ich dann mit einer Methode mit dem Inhalt.



```
String sDefault = e0.getAttribute("default");
	boolean bDefault = toBoolean(sDefault);

	Element vnElement = (Element)e0.getFirstChild();
	String sValuename = getTextValue(vnElement).trim();

	Element vhElement = (Element)vnElement.getNextSibling();
	String sValuehelp = getTextValue(vhElement).trim();

	Element eElement = (Element)vhElement.getNextSibling();
	String sEditable = getTextValue(eElement).trim();
	boolean bEditable = toBoolean(sEditable);

        ....
```

Wie kann ich die xml gegen die dtd prüfen? 

Wie funktioniert das dann mit dem Doc-Type?

Vielen Dank nochmal


----------



## Bleiglanz (12. Okt 2005)

> Wenn ich die dtd weglassen kann ich die Wert aus der
> xml nicht lesen. Kann sie irgendwie beim einlesen und
> zerlegen in Java nicht zuordnen. Findet dann nichts
> Habe ich die dtd funktioniert es.


das ist quatsch

das Problem ist wahrscheinlich, dass ohne die DTD der ganze Whitespace auch als Kindelemente reinwandert, also getFirstChild nicht funktioniert...

entweder du programmierst "robuster" oder du beisst in den sauren Apfel und konfigurierst deinen Parser so, dass er die DTD aus dem Jar-Archiv nachladen kann...


----------



## niko022 (12. Okt 2005)

Welches  ist der leichtere Weg?


----------



## niko022 (12. Okt 2005)

Wie kann ich es robuster machen?


----------



## Bleiglanz (12. Okt 2005)

nicht auf FirstChildren oder sowas verlassen

immer den Elementtypen abfragen, und leere Textknoten einfach ignorieren

ggf. Element#getElementsByTagName(String tagname) 

verwenden um "Knoten" zu finden 

usw.


----------



## niko022 (12. Okt 2005)

Dann könnte ich die einzelnen Elemente getElementByTagName auslesen.
Sollte ca. so aussehen oder? 


```
Element vnElement = (Element)e0.getElementByTagName(    TAGNAME    );
String sValuename = getTextValue(vnElement).trim();
```

TAGNAME kann Variable , Value .... sein oder?

Wie kann ich innerhalb der Tags die Attribute auslesen?


----------



## Bleiglanz (12. Okt 2005)

lern halt mal die API

Element#getAttribute


----------

