![]() |
[JAVA] XML
Hallo Leute.
Stehe gerade vor einem XML Problem. Ich habe ein String Array mit einer unbekannten Anzahl von Elementen, und möchte diese nun unter dem RootNode dynamisch erzeugen.
Code:
aus diesem Array soll nun folgendes erstellt werden:
String[] elements = { "eine" , "unbekannte" , "element" , "anzahl" };
XML-Code:
Des weiteren ist es möglich, dass ein Knoten mehrmals benutzt wird.
<root>
<eine> <unbekannte> <element> <anzahl/> </element> </unbekannte> </eine> </root> Also muss ein möglicherweise schon bestehender Knoten "gefunden" werden...
Code:
Wofür das ganze?
Strings[] elements2 = { "eine" , "andere" , "element" , "anzahl" };
Ich schreibe mir gerade eine eigene Properties Klasse, damit ich Daten strukturierter speichern kann. Soll später so ähnlich aussehen wie die JvXmlAppStorage der JEDIs (hofffe, hab den Namen richtig in Erinnerung...) Hab schon ein bischen rumprobiert, aber ich hab auf DOM Ebene noch nicht mit XML gearbeitet. Also bitte nicht schlagen, wenn die Lösung allzu simpel ist^^ |
Re: [JAVA] XML
Also wenn du grundätzlich nur eine Datei in den ram in arrays laden willst um sie später wieder zu speichern solltest du darüber nachdenken, ob xml die richtige Entscheidung ist ^^.
JSON wäre da viel schneller, hat deutlich weniger overhead undlibs für Java gib' it auch genug: ![]() Wenn du trotzdem unbedingt xml verwenden willst, dann könntest du einfach in deinen strings mit string replace alle < durch < alle > durch > und alle & durch & ersetzen und dann noch die xml-tags drumrumhauen und du hast deine xml-datei sehr schnell generiert. So... jetzt werde ich leider gerade zum Frühstück gerufen^^. EDIT: so, da bin ich wieder. Zum auslesen kannst du dann SAX ( ![]() |
Re: [JAVA] XML
Nein, ich will nicht nur ein paar Arrays abspeichern^^
Was ich möchte, ist eine strukturierte Möglichkeit, Daten abzuspeichern, zum Beispiel Fensterpositionen und andere Sachen. Geht natürlich auch mit den Standard Properties, aber leider bieten diese mir nicht die Möglichkeit, eine Struktur in die Ausgabe zu bringen. Prototyp: writeInteger( String Key, Integer Value ); Beispiel: writeInteger( "window.position.left", 100 ); Beispiel: writeInteger( "window.position.top", 100 ); Die oben getätigten Eingaben sollten nun beim speichern der Einstellungen einen solchen output erzeugen:
XML-Code:
--> Der Key wird durch "." geteilt, (das im ersten Post angesprochene String Array), welches wiederum die Unterknoten definiert.
<root>
<window> <position> <left type="integer">100</left> <top type="integer">100</top> </position> </window> </root> --> Das Type Attribut ist nur ne Hilfestellung für menschliche Leser, um den erwarteten Datentyp anzuzeigen Dazu sollte vielleicht noch gesagt werden, dass nicht jeder Aufruf der write Funktionen etwas in die Ausgabedatei schreibt, sondern diese Werte werden zuerst in eine Liste (Hashtable like) geschrieben und beim Aufruf der Speicherfunktion dann in die Datei ausgelagert. (und genau da liegt mein Problem...) Ob XML dafür die optimale Lösung ist, weiß ich nicht, aber möglich ist es auf jeden Fall^^ |
Re: [JAVA] XML
Zitat:
Heisst das, du hast eine Liste, die dann so aussieht: [ ["window.position.left",100], ["window.position.top",100], ... ] :?: Nun... Das musst du auseinander nehmen. Oder eine API finden, die das für dich machen, aber irgendwer muss es auseinander nehmen... |
Re: [JAVA] XML
Genau!
Die ArrayList enthält StorageItem Objekte, die durch die write... Funktionen erzeugt werden. Das StorageItem Objekt enthält 3 Eigenschaften:
Code:
Das StorageItem Objekt, welches bei dem oben genannten Beispiel erzeugt würde, würde dann so aussehen:
String Key
String Type Object Value
Code:
Beim speichern der ArrayList werden dann die einzelnen Elemente durchlaufen.
Key=window.position.left
Type=integer Value=100
Code:
Das Problem ist nicht technischer, sondern geistiger Natur. Ich weiß zwar, wie ich einen einzelnen Knoten erstelle (-->RootNode), aber nicht, wie ich in möglichst wenig Schritten neue Knoten und deren Unterknoten erstellen kann.
public void saveToFile (
String FileName ) { try { /* Dokument erstellen */ Document doc = domBuilder.newDocument (); /* Root Knoten erstellen */ Element rootNode = doc.createElement ( RootNode ); doc.appendChild ( rootNode ); String[] elements; // Data ist die ArrayList... for( int i = 0 ; i < Data.size() ; i++ ) { elements = Data.get(i).getKey.split("\\."); // Hier liegt das Problem. Das elements Array enthält jetzt die // zu erstellenden Knoten. // Aber wie erstelle ich jetzt die einzelnen Knoten und deren Unterknoten, // Bzw. prüfe auf die Existenz eines Knotens??? } /* Speichern */ TransformerFactory tranFactory = TransformerFactory.newInstance (); Transformer aTransformer = tranFactory.newTransformer (); Source src = new DOMSource ( doc ); Result dest = new StreamResult ( new File ( FileName ) ); aTransformer.transform ( src, dest ); } catch(Exception e) { System.err.println (e.toString ()); } } |
Re: [JAVA] XML
Also unmöglich ist das sicherlich nicht, aber performancetechnisch keine gute Idee und ich frage mich grundsätzlich wieso du das so machst und überhaupt.
Es wäre viel leichter, du würdest deine Liste so organisieren:
Code:
durch die Struktur kannst da dann nämlich rekursiv durchgehen und alles in xml speichern.
[
{ "name":"window", "wert": [ { "name":"position", "wert": [ { "name":"left", "wert":100 }, { "name":"top", "wert":100 } ] } ] } ] Es würde auch schon helfen, wenn du deine Liste zumindest nach den Keys sortierst... |
Re: [JAVA] XML
Die von dir beschriebene Listenstruktur ist ja identisch mit der, die ich für der XML Datei skizziert habe. Dazu müsste ich ja noch nicht mal viel geändert werden. Könnte dann so oder so ähnlich aussehen?
Code:
Oder müsste ich an den entsprechenden Stellen ne neue Liste anstelle eines StorageItems einhängen?
key=window
type=container value=ArrayList<StorageItem> { position } key=position type=container value=ArrayList<StorageItem> { left } key=left type=integer value=100 Hab jetzt die Liste so wie von dir beschrieben implementiert, zusätzlich noch um Beschreibungs- und Datentypfelder erweitert. Lesen und schreiben der Werte funzt, nur mit Export (bzw. dann auch später Import) über XML tue ich mich irgendwie sehr schwer. :gruebel: Vielleicht darf ich nochmal um Hilfe bitten? |
Re: [JAVA] XML
Ne Woche vorbei, und keiner weiß Rat? :(
Ich versuche nach wie vor, die vorgestellte Listenstruktur in ein JDOM XML Dokument zu packen, wobei jeder Eintrag in der Liste ein eigenes XML Element sein soll. Wie schon weiter oben erwähnt, ginge das, zumindest theoretisch, durch eine Funktion die die Liste durchläuft, und die Elemente in das Root Element einhängt. Hab zwar durch das ausprobieren momentan keine funktionierende Version mehr, aber das einzigeste, was ich zu Stande bekommen habe, ist, dass die einzelnen Elemente direkt in das Root Element eingehängt wurden, und nicht wie beabsichtigt, als Unterknoten. Vielleicht kann mir jemand mit ein "bischen" (je nach dem wie viel das ist -_-) Code aushelfen? Danke |
Re: [JAVA] XML
Das sah doch eigentlich schon ganz gut aus, was du da geschrieben hast...
Jede StorageItem hat einen key, ein typ und ein value. Du solltest vielleicht subnodes von value trennen. Mal schnell Quick&Dirty zusammengehauen:
Code:
Du nimmst wahrscheinlich eher einen StringBuilder als einen String in toString, um die Performance zu verbessern und musst noch was einbauen, damit der qt schön formatiert wird und nicht in einer Zeile hintereinander weg ausgegeben wird.
class StorageItem
{ public String key; public String value; public String type; public ArrayListe<StorageItem> subnodes; public String xmlFormat(String s) { return s.replaceAll('&','&').replaceAll('<','<').replaceAll('>','>'); } public String toString() { String result ="<"+this.xmlFormat(key)+">"; for(int i=0; i<subnodes.length; i++) result +=subnodes.get(i).toString(); result +=this.xmlFormat(value) + "</"+ this.xmlFormat(key) + ">"; } } Aber so rein von der Theorie müsste das so klappen... Oder gibt es damit noch ein Problem? |
Re: [JAVA] XML
Danke für die schnelle Antwort.
Hab die Idee, SubNodes von Value zu trennen einfach mal übernommen. Deine Ausgabemethode funktioniert (nach einigen Änderungen^^) auch, ist jedoch nicht ganz das, was ich wollte. Ich wollte (muss?) das ganze über nen DOM|JDOM regeln, da ich die Daten ja auch wieder einlesen können muss. Und genau da liegt mein Problem. Dabei spielt die Form der Ausgabe, ob über eine XML Schnittstelle oder so wie du es vorgeschlagen hast, über einen String ja keine Rolle, sofern gültiges XML produziert wird. Ich werd einfach nochmal ein bischen rum tüfteln, vielleicht krieg ich das ja irgendwie mit deinem Funktionsansatz hin... :P |
Re: [JAVA] XML
Zitat:
Zitat:
|
Re: [JAVA] XML
Zitat:
Aber genau das ist das Problem ;) Ich habe es weder hinbekommen, mit JDOM das angesprochene XML Dokument zu erstellen noch es wieder auszulesen. Ok, das Auslesen funzt schonmal teilweise... Ich komme zwar mit JDOM (SaxBuilder) an die Werte, aber nicht über die einzelnen Kind Knoten, sondern nur über den Root Node, durch den ich auch auf untergeordnete Knoten welche keine direkten "Kinder" des Root Node sind, zugreifen kann (Also eine Liste, wo jedes XML Element OHNE "Verschachtelung" aufgeführt wird). Das macht es schwieriger, wenn nicht gar unmöglich, die gelesenen Daten wieder in die Liste zu packen... |
Re: [JAVA] XML
php enthält eine Portierung des sax-parsers, mit dem ich schon gearbeited habe...
Und zumindest da ist das ganz einfach... Und unter ![]() Wo ist dein Problem damit? Wenn du mir sagst, wo du nicht weiterkommst, kann ich dir vielleicht helfen. Aber du verstehst sicherlich, dass ich keine Motovation habe dir jetzt den kompletten qt zu schrieben ;-). |
Re: [JAVA] XML
Zitat:
Also, der Output über JDOM funktioniert jetzt. Folgende Funktion erzeugt den nachfolgend gezeigten XML Output.
Code:
public Element toElement ()
{ /* Element für sich selbst mit dem eigenen Namen erstellen */ Element self = new Element ( Key ); /* Prüfen, ob das Element selbst ein Container ist */ if( SubNodes.size () == 0 /*!Type.equalsIgnoreCase ( "container" )*/ ) { /* Kein Container --> Datenelement * Die relevanten Daten extrahieren */ /* Den Datentyp speichern */ self.setAttribute ( "type", Type ); /* Beschreibung speichern (Nur falls vorhanden) */ if( !Description.equalsIgnoreCase ( "" ) ) self.setAttribute ( "description", Description ); /* Den Datenwert speichern */ self.setText ( Value.toString () ); } else { /* Container Element --> Enthaltene Elemente durchlaufen */ for( int i = 0 ; i < SubNodes.size () ; i++ ) { /* Kind Elemente hinzufügen */ self.addContent ( SubNodes.get ( i ).toElement () ); } } /* Erstelltes Element zurückgeben */ return self; }
XML-Code:
<?xml version="1.0" encoding="UTF-8"?>
<root> <ein> <anderer> <pfad> <zu> <einem> <anderen> <wert type="string" description="Ein ziemlich uninteressanter Testwert!">Hallo</wert> </anderen> </einem> </zu> </pfad> </anderer> </ein> <window> <position> <left type="short" description="Was war das doch gleich?">100</left> </position> </window> </root> Jetzt muss ich das natürlich wieder auslesen können.
Code:
Erstellt wird dabei aber leider nur so was:
public void loadFromFile (
String FileName ) { try { SAXBuilder sax = new SAXBuilder (); Document doc = sax.build ( FileName ); loadFromElement( doc.getRootElement (), root ); } catch (IOException ex) { ex.printStackTrace (); } catch (JDOMException ex) { ex.printStackTrace (); } } private StorageItem loadFromElement ( Element item, StorageItem data ) { Iterator itr = (item.getChildren ()).iterator (); Iterator otr = null; while(itr.hasNext ()) { Element current = (Element)itr.next (); otr = (current.getChildren ()).iterator (); /* Container? */ if( otr.hasNext () ) { data.SubNodes.add ( loadFromElement ( (Element)otr.next (), data ) ); } /* Daten */ else { try { data.SubNodes.add ( new StorageItem ( current.getName (), current.getAttribute ( "type" ).getValue (), current.getText (), current.getAttribute ( "description" ).getValue () ) ); } catch (InvalidStorageData ex) { ex.printStackTrace (); } catch (InvalidXmlAttributeContentException ex) { ex.printStackTrace (); } catch (InvalidXmlElementNameException ex) { ex.printStackTrace (); } } } return data; }
Code:
Hab irgendwie gerade en Brett vorm Kopf, denn ich seh den Fehler nicht :oops: ...
"name":"root"
"list": [ { "name":"wert" "type":"string" "description":"..." "wert":"hallo" [ { null } ] "name":"root" "list": [ { // Enthält alle Elemente des root Elementes [erstes Element in der Liste] } ] "name":"root" "list": [ { // Enthält alle Elemente des root Elementes [erstes Element in der Liste] } ] "name":"root" "list": [ { // Enthält alle Elemente des root Elementes [erstes Element in der Liste] } ] "name":"left" "type":"short" "description":"..." "wert":"hallo" [ { null } ] "name":"root" "list": [ { // Enthält alle Elemente des root Elementes [erstes Element in der Liste] } ] } ] |
Re: [JAVA] XML
Code:
Du übergibst data UND
private StorageItem loadFromElement (
Element item, StorageItem data )
Code:
returnst es?
return data;
Wenn du dir deinen Quelltext nochmal genau ansiehst könnte das die Fehlerquelle sein. Zumindest ist es eine. Ich würde mal sagen du hörst einfach auf data zu übergeben und deklarierst es als eine lokale Variable der Funktion, die du, wie bisher auch returnst. |
Re: [JAVA] XML
Zitat:
Aber jetzt funktioniert alles, wie es sollte :-D Danke für deine tatkräftige Unterstützung :thumb: |
Re: [JAVA] XML
Zitat:
Sry das OT... Aber kann du mir ghanz kurz sagen, wo dein Nick herkomtm? Der kommt mir so verdammt bekannt vor... |
Re: [JAVA] XML
[offtopic]
Wird eigentlich Dúnedain geschrieben und kommt aus dem "Herr der Ringe". Aragorn tritt anfangs unter diesem Namen auf, obwohl der Name eigentlich eine Bevölkerungsgruppe bzw. ein Königreich bezeichnet. [/offtopic] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz