xml schreiben und parsen in java

AleX

Erfahrenes Mitglied
hi,
wollte fragen ob hier jemand schon mal was mit java in verbindung mit xml gemacht hat??? (xml als lokale datenablage)

Nun mein prob:
Ich bräuchte unbedingt ein einfaches Beispiel, in dem eine xml datei aus java aus geschrieben wird und danach wieder eingelsen, und zwar so dass man auf bestimmte werte zugreifen kann.

Hab das schon gemacht, als document objekt model DOM und mit dem SAX hab ich es mir auch angesehen, aber ich schaff es einfach nicht, die xml korrekt als DOM einzulesen und dann per Xpath(oder anders, falls es noch eine andere möglichkeit gibt) auf bestimmte werte zuzugreifen...

Wenn sich jemand opfern würde und eine kleines prog mit funktionierendem schreiben und einlesen posten würde, dann *freu*.

:) please, ist wirklich wichtig und ich komm einfach nicht weiter
 
Es gibt 3 möglichkeiten

DOM, SAX, JDOM

DOM liest das ganze XML Document in einen Baum ein und mann kann über die verschiedene Elemente navigieren.
Das ist recht Tricky denn auch ein einzelner Whitespace im Document kann (DTD abhängig) eine Textnode sein.

SAX durchläuft das Dokument und reagiert auf Nodes durch bestimmte Handler. Sehr schnell und gut beim lesen.

JDOM ist OpenSource von der ApacheGroup (Qualität!) und ist dabei demnächst in den Java Standard mit aufgenommen zu werden. Ist mittlerweile defacto Standard. Und auch mein Favorit weil es:
a) JavaTypischer
b) Unkomplizierter
ist.

Also einlesen mit SAXBuilder
path der komplette pfad zur XML Datei
Code:
import org.jdom.*;
import org.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
..
..
SAXBuilder sxbuild 
     = new SAXBuilder();
InputSourc is 
     = new InputSource(path);
Document doc = sxbuild.build(is);
Element root = doc.getRootElement();

nun hast du ein Dokument eingeselen wenn du ein Document erstellen willst geht das so:

Code:
Element root = new   
    Element("StartElement");
Document doc = new Document(root);

Dann kannst du neue Elemente anhängen
Code:
root.appendChild(new Element("kindElement"));
usw

Ausgegeben wird das ganze dann mit
org.jdom.output.XMLOutputter
der die Zeichenfolge fürs Einrücken und
denn boolean wert ob neue Elemente in neue Zeilen gesetzt werden.

Zudem brauchen wir noch einen FileOutputStream welche für die reine Dateioperation zuständig ist. Dieser wird an den Outputter noch mit dem Document zusammen zum Ausgeben übergeben.


Code:
XMLOutputter outputter 
  = new XMLOutputter(" ",true);
FileStream output
    = new FileOutPutStream("file.xml");
outputter.output(doc,output);

Damit wurde das File erstellt

hoffe das hilft
 
jo big thx! :)

hat mir sehr weitergeholfen, ich hatte nur noch ein kleines prob mit der logik bzw. Verständnis.

Hab es jetzt folgendermaßen mit DOM gelöst: (schreiben)
Allerdings bin ich mir nicht sicher, ob das alles so professionel gelöst ist, also falls was mieses drin ist, bitte sagen.



import java.io.*;
import org.w3c.dom.*;
import com.sun.xml.tree.XmlDocument;

public class XmlWriter
{
public static void main(String[] args)
{
XmlWriter writer = new XmlWriter();
XmlDocument doc = writer.createFile();
try
{
writer.writeFile(doc, args[0]);
}
catch (IOException e)
{
System.err.println("Fehler beim Schreiben: ");
System.err.println(e);
}
}

public XmlDocument createFile()
{
XmlDocument doc = new XmlDocument();

Text text = doc.createTextNode("viel Text");

Element child2 = doc.createElement("Child2");
child2.appendChild(text.cloneNode(false));

Element child1 = doc.createElement("Child1");
child1.appendChild(text.cloneNode(false));
child1.appendChild(child2);

Element durchlauf = doc.createElement("Durchlauf");
Attr nr = doc.createAttribute("Nummer");
durchlauf.setAttributeNode(nr);

Element root = doc.createElement("Teil");
root.setAttribute("root", "true");
for (int i = 0; i <= 1; i++)
{
nr.setValue((new Integer(i)).toString());
root.appendChild(durchlauf.cloneNode(false));
root.appendChild(child1.cloneNode(true));
}

Comment kommentar = doc.createComment("Kommentar");
doc.appendChild(kommentar);
doc.appendChild(root);

return doc;
}

public void writeFile(XmlDocument doc, String file)
throws IOException
{
FileOutputStream out = new FileOutputStream(file);
doc.write(out);
out.close();
}
}


Jetzt nur noch eine Frage: Einlesen mit SAX - kein prob wenn ichs bloss wiedergeben möchte, aber wenn ich auf bestimmte werte zugreifen will, da ich praktisch eine applikation schreibe, wo die einstellungen in xml gespeichert werden, geht das doch mit xpath?! oder?

Auf jedenfalls schon mal ein fettes lob von mir, für die mühe! ;)
 
Ich seh nichts unprofessionelles an deinem
Code.

DOM ist die Standardimplementierung vom w3c und sich daran zu halten ist immer gut :)

Nun aber eine änderrung würde ich schon nehmen. Und zwar den XMLOutputter dieser ist ein wunderbares mittel XML Dokumente gleich mit angenehmen Whitespaces darzustellen.

Nun du greifst auf Werte in JDOM
Element elem = root.getChild("MyElement");
String myValue = elem.getText();

Mit DOM geht das wenn ich mich recht errinnere:
Durchlaufe die Children:
Code:
NodeList childs = root.getChildNodes();
for(int x = 0;x < childs.getLengt();x++)
{
 Node tmp = childs.item(x);
  if((tmp.getNodeType()==Node.TEXT_NODE)     
  &&(tmp.getNodeName.equals("gesucht"))  
  {
    String myValue = tmp.getNodeValue();
  }   
       
}

Also mann sieht durch dir relativ Komplizierte DOM implementierung fährst du bei abfrage von werten mit JDOM besser. Weil JDOM Text nicht als Textnode behandelt wie in DOM sondern dich über die Methode getText() eines JDOM elements an dessen inhalt ranlässt
 
nochmal danke.

werd das jetzt mal mit dem JDOM machen. ;)

Denn ich bin schon auch deiner Meinung, dass es doch etwas kompliziert bzw. einfach umständlich mit DOM ist, insbesondere beim Einlesen.
 
ok, ich glaub jetzt habe ich alle deine anweisungen befolgt ;)

So sieht das ganze jetzt mit JDOM aus:

Code:
import org.jdom.Element;
import org.jdom.Document;
import org.jdom.output.XMLOutputter;

import java.io.IOException;
import java.io.FileOutputStream;

public class writer {
    public static void writer_start(String filename, String[] elementName, String[] content) {
        writer writer = new writer();
        Document doc = writer.createFile(filename, elementName, content);
        try {
            writer.writeFile(doc, filename);
        } catch (IOException e) {
            System.err.println("Fehler beim Schreiben: " + e);
        }//catch
    }//main

    public Document createFile(String filename, String[] elementName, String[] content) {

        Document doc = new Document();
        Element rootElement = new Element("root");
        doc.setRootElement(rootElement);


        // -----------> XML-Aufbau
        for (int i = 0; i < elementName.length || i < content.length; i++) {
            Element element = new Element(elementName[i]);
            element.addContent(content[i]);
            rootElement.addContent(element);
        }
        // -----------> XML-Aufbau end


        // -----------> XML-Einlesen test
        try{
        Element el = rootElement.getChild("one");
        String tagValue = el.getText();
        System.out.println(tagValue);
        }catch (Exception e){
            System.err.println("Fehler beim Einlesen: xml-tag nicht gefunden");
        }
        // -----------> XML-Einlesen test end


        return doc;
    }//createFile

    public void writeFile(Document doc, String filename) throws IOException {
        XMLOutputter outputter = new XMLOutputter(" ", true);
        FileOutputStream output = new FileOutputStream(filename);
        outputter.output(doc, output);

    }//writeFile
}//writer
 
probs gehen weiter... :)

jetzt meld ich mich doch noch mal...

Also folgendes prob: Ziehe mir von einem server ein xml file, welches ich daraufhin einem TableModel übergeben möchte...

Nur jetzt sieht die formatierung der xml so aus:
Code:
  <?xml version="1.0" encoding="ISO-8859-1" ?> 
- <products>
- <customer id="0027">
- <product unid="3B6A03E551ABF630C1256C7D00288448">
  <item name="ProductManufacturer" value="Liebherr" /> 
  <item name="ArticleCategory" value="Kräne" /> 
  <item name="ProductModel" value="LT 10-45 S" /> 
  </product>
- <product unid="410E1C3F452C117DC1256C7D0028D350">
  <item name="ProductManufacturer" value="Sonstige Hersteller" /> 
  <item name="ArticleCategory" value="Kräne" /> 
  <item name="ProductModel" value="S 15" /> 
  </product>
usw...

und ich brings einfach nicht fertig, z.B. von customer mit der id 0025 die value Liebherr aus ProductManufacturer auszulesen...
(mit JDOM)

Ansonsten sollte es ja dann kein problem sein, die sachen in einen array bzw object zu legen, die wiederrum in einen vektor und das dann einem tablemodel zu übergeben... <- wenn ich mich irre bitte sagen :)
 
doc ist geparste XMLDocument

Element products doc.getRootElement();
Element costumer = products.getChild("customer");
String id = costumer.getAttribute("id");

sorry falls du etwas nachbessern musst. ich habe das aus dem gedächtnis geschrieben aber die api-dokumentation hast du ja um eventuelle Fehler herauszubekommen
 
Zurück