+ Antworten
Ergebnis 1 bis 12 von 12

Thema: XmlJavaTypeAdapter füllt die Liste nicht

  1. #1
    User short Themenstarter

    Registriert seit
    12.04.2014
    Fachbeiträge
    16
    Genannt
    0 Post(s)
    Hallo liebe Community,
    der Mist bringt mich langsam echt auf die Palme.

    Ich hab eine XML Datei, die schaut im groben so aus:
    XML Code:
    1. <jvx-model>
    2.     <geometries>
    3.         <geometry name="Mesh">
    4.             <pointSet dim="3">
    5.                 <points num="14290">
    6.                     <p>0.309469 -0.921392 0.450065</p>
    7.                     <p>-0.246077 0.582705 0.060732</p>
    8.                     <!-- 14288 weitere Punkte -->
    9.                 </points>
    10.             </pointSet>
    11.         </geometry>
    12.     </geometries>
    13. </jvx-model>

    So. Diese Datei möchte ich auslesen, daher habe ich mir eine Struktur überlegt.
    Ich hab JVXBean.java (die enthält einen XmlElementWrapper(name="geometries"), GeometryBean.java, PointSetBean.java.
    Eigentlich wollte ich auch in die PointSetBean ein XmlElementWrapper für "points" hinzufügen, allerdings hat das nie ganz geklappt, weil es nicht funktionierte, einen XmlElementWrapper UND ein XmlJavaTypeAdapter gleichzeitig zu benutzen... (es kamm dann immer die Fehlermeldung, es muss sich bei dem Typen um eine Collection oder ein Array handeln... meines war übrigens eine ArrayList<double[]>. Nach einigem suchen via google fand ich einen BugReport für JAXB zu diesem problem...)

    Also dachte ich mir, was sollst, schreibste dir halt noch eine Klasse, PointsBean.java. Die schaut jetzt so aus:
    Java Code:
    1. package meshjoinery.geometry.beans;
    2.  
    3. import java.util.LinkedList;
    4.  
    5. import javax.xml.bind.annotation.XmlAttribute;
    6. import javax.xml.bind.annotation.XmlElement;
    7. import javax.xml.bind.annotation.XmlRootElement;
    8. import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    9.  
    10. @XmlRootElement( name = "points" )
    11. public class PointsBean {
    12.     private int numOfPoints;
    13.    
    14.     @XmlElement( name = "p" )
    15.     @XmlJavaTypeAdapter( PointAdapter.class )
    16.     public LinkedList<double[]> pointList = new LinkedList<double[]>();
    17.    
    18.     /**
    19.      * @return the numOfPoints
    20.      */
    21.     @XmlAttribute( name = "num" )
    22.     public int getNumOfPoints() {
    23.         return numOfPoints;
    24.     }
    25.  
    26.     /**
    27.      * @param numOfPoints the numOfPoints to set
    28.      */
    29.     public void setNumOfPoints(int numOfPoints) {
    30.         this.numOfPoints = numOfPoints;
    31.     }
    32. }

    Das ist jetzt mein letzter Testversuch, daher diese wirren Sichtbarkeiten... ich hatte davor schon alles andere Probiert aber das haut nicht hin.
    Jetzt werfen wir einen Blick auf PointAdapter.java:
    Java Code:
    1. package meshjoinery.geometry.beans;
    2.  
    3. import javax.xml.bind.annotation.adapters.XmlAdapter;
    4.  
    5. public class PointAdapter extends XmlAdapter<String, double[]> {
    6.     @Override
    7.     public double[] unmarshal(String v) throws Exception {
    8.         //usually split lists at whitespace characters
    9.         String[] arguments = v.split(" ");
    10.         double[] points = new double[arguments.length];
    11.         // System.out.println("-> " + v);
    12.         for ( int i = 0; i < arguments.length; i++ )
    13.             points[i] = Double.parseDouble( arguments[i] );
    14.        
    15.         return points;
    16.     }
    17.  
    18.     @Override
    19.     public String marshal(double[] v) throws Exception {
    20.         String str = "";
    21.         for ( int i = 0; i < v.length; i++ )
    22.             str += Double.toString(v[i]) + " ";
    23.         return str.substring(0, str.length()-1);
    24.     }
    25. }

    Bis hier hin geht alles gut... nur hat meine LinkedList<double[]> nach dem einlesen die Länge 0! Es wurden also keine Arrays in die Liste geschrieben...
    Wenn ich die System.out.println in PointAdapter wieder rein nehme, sehe ich auch das die Methode brav für alle <p></p> ausgeführt wird.
    Wenn ich statt der LinkedList<double[]> eine LinkedList<String> nehme und den adapter weglasse, ist die Liste ebenfalls vollständig.
    Wenn ich für den Adapter nicht von String->double[] sondern von String->String umformen lasse und einfach jeden Wert in <p></p> in "ROFL" änder, dann funktioniert das auch... In jedem Eintrag der LinkedList<String> steht dann ROFL, genau 14290 mal...

    Aber völlig egal was ich tue... er füllt diese verdammte Liste einfach nicht mit dem Double-Array...
    Ich habs mit Double[] (statt double[]) versucht. Ich hab statt LinkedList alle möglichen Listen versuchen, einschließlich List<double[]>... Nichts funktioniert.

    Mir gehen langsam die Ideen aus, die ich probieren könnte...
    Mir wäre es auch wesentlich lieber, wenn ich mir die PointsBean sparen könnte...
    In der PointSetBean hatte ich dann sowas zu stehen
    Java Code:
    1. @XmlPath("points/@num")
    2. public int num; // Attribute von <points/>
    3.  
    4. @XmlElementWrapper(name = "points")
    5. @XmlElement(name = "p")
    6. @XmlJavaTypeAdapter( PointAdapter.class )
    7. public ArrayList<double[]> points = new ArrayList<double[]>(15000);

    Aber dann kam es zur oben erwähnten Fehlermeldung...
    Ich verzweifel Langsam ,ich hoffe ihr könnt mir helfen. Wenn ihr mehr Code braucht kriegt ihr denn natürlich. Ich dachte nur es müsste reichen was ich euch hier gebe. Sonst wirds schnell unübersichtlich.
    Ach ja einlesen tu ich das ganze sehr simpel...
    Java Code:
    1. JVXBean jvx = JAXB.unmarshal(path.toFile(), JVXBean.class); // path ist der Pfad zur XML-Datei
    Und bei den ganzen Bean-Klassen liegt noch eine jaxb.properties im package worin steht:
    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

    Das brauchte ich um @XmlPath verwenden zu können, stand irgendwo im Netz.

    Vielen Dank für eure Hilfe

    Liebe Grüße
    Highchiller

    *** Edit ***

    PS: Ein anderer Ansatz der klappt, wäre übrigens dieser hier. Die PointSetBean.java schaut jetzt so aus:
    Java Code:
    1. package meshjoinery.geometry.beans;
    2.  
    3. import java.util.ArrayList;
    4.  
    5. import javax.xml.bind.annotation.XmlAccessType;
    6. import javax.xml.bind.annotation.XmlAccessorType;
    7. import javax.xml.bind.annotation.XmlAttribute;
    8. import javax.xml.bind.annotation.XmlElement;
    9. import javax.xml.bind.annotation.XmlElementWrapper;
    10. import javax.xml.bind.annotation.XmlRootElement;
    11. import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    12.  
    13. import org.eclipse.persistence.oxm.annotations.XmlPath;
    14.  
    15. @XmlRootElement( name = "pointSet" )
    16. public class PointSetBean {
    17.    
    18.     @XmlAttribute( name = "dim" )
    19.     private int dimension;
    20.    
    21.     //@XmlPath("points/@num")
    22.     private int numberOfPoints;
    23.    
    24.     @XmlElementWrapper(name = "points")
    25.     @XmlElement(name = "p")
    26.     @XmlJavaTypeAdapter( PointAdapter.class )
    27.     private ArrayList<double[]> points;
    28.    
    29.     //@XmlElement( name = "points" )
    30.     //private PointsBean points;
    31.    
    32.     public ArrayList<double[]> getPoints(){
    33.         if ( points == null ) points = new ArrayList<double[]>(numberOfPoints);
    34.         return points;
    35.     }
    36.    
    37.     public void setPoints(ArrayList<double[]> points){
    38.         this.points = points;
    39.     }
    40.    
    41.     public int getNumberOfPoints(){
    42.         return numberOfPoints;
    43.     }
    44.    
    45.     public void setNumberOfPoints(int numberOfPoints){
    46.         this.numberOfPoints = numberOfPoints;
    47.     }
    48.    
    49.     /**
    50.      * @return the dimension
    51.      */
    52.     public int getDimension() {
    53.         return dimension;
    54.     }
    55.  
    56.     /**
    57.      * @param dimension the dimension to set
    58.      */
    59.     public void setDimension(int dimension) {
    60.         this.dimension = dimension;
    61.     }
    62. }
    (hierfür musste ich die jaxb.properties Datei entfernen... damit ist es nicht mehr möglich das Attribut von points auszulesen... aber er füllt die Liste vollständig UND KORREKT mit allen Punkten als double[]).

    Wenn ich hier
    Java Code:
    1. @PathXml( "points/@num" )
    wieder reinnehme UND die jaxb.properties datei wieder hinzufüge. Dann kommt die Fehlermeldung:
    javax.xml.bind.DataBindingException: javax.xml.bind.JAXBException:
    Exception Description: XmlElementWrapper is only allowed on a collection or array property but [points] is not a collection or array property.
    Hier die gesamter Fehlerstack, falls es hilft:
    javax.xml.bind.DataBindingException: javax.xml.bind.JAXBException:
    Exception Description: XmlElementWrapper is only allowed on a collection or array property but [points] is not a collection or array property.
    - with linked exception:
    [Exception [EclipseLink-50015] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.JAXBException
    Exception Description: XmlElementWrapper is only allowed on a collection or array property but [points] is not a collection or array property.]
    at javax.xml.bind.JAXB.unmarshal(JAXB.java:156)
    at meshjoinery.factory.JVXFactory.readJVX(JVXFactory.java:23)
    at meshjoinery.components.LoaderPanel$2.actionPerformed(LoaderPanel.java:52)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290)
    at java.awt.Component.processMouseEvent(Component.java:6527)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6292)
    at java.awt.Container.processEvent(Container.java:2234)
    at java.awt.Component.dispatchEventImpl(Component.java:4883)
    at java.awt.Container.dispatchEventImpl(Container.java:2292)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
    at java.awt.Container.dispatchEventImpl(Container.java:2278)
    at java.awt.Window.dispatchEventImpl(Window.java:2739)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:719)
    at java.awt.EventQueue$4.run(EventQueue.java:717)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
    Caused by: javax.xml.bind.JAXBException:
    Exception Description: XmlElementWrapper is only allowed on a collection or array property but [points] is not a collection or array property.
    - with linked exception:
    [Exception [EclipseLink-50015] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.JAXBException
    Exception Description: XmlElementWrapper is only allowed on a collection or array property but [points] is not a collection or array property.]
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:1021)
    at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:174)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:165)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:152)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:112)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:102)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
    at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
    at javax.xml.bind.ContextFinder.find(ContextFinder.java:390)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
    at javax.xml.bind.JAXB$Cache.<init>(JAXB.java:112)
    at javax.xml.bind.JAXB.getContext(JAXB.java:139)
    at javax.xml.bind.JAXB.unmarshal(JAXB.java:153)
    ... 39 more
    Caused by: Exception [EclipseLink-50015] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.JAXBException
    Exception Description: XmlElementWrapper is only allowed on a collection or array property but [points] is not a collection or array property.
    at org.eclipse.persistence.exceptions.JAXBException.invalidElementWrapper(JAXBException.java:187)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.finalizeProperties(AnnotationsProcessor.java:983)
    at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.processClassesAndProperties(AnnotationsProcessor.java:282)
    at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:150)
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:1017)
    ... 56 more


    Also irgendwas ist einfach mal kaputt -.-

  2. #2
    User Megabyte Avatar von Timothy_Truckle
    Registriert seit
    01.08.2013
    Ort
    Wasserkuppe
    Fachbeiträge
    1.329
    Genannt
    85 Post(s)
    Blog-Einträge
    5
    wie stabil ist den das XML schon? Ist eine Änderung an der XML-Stuktur noch akzeptabel?
    XML Code:
    1.     <jvx-model>
    2.         <geometries>
    3.             <geometry name="Mesh">
    4.                 <pointSet dim="3">
    5.                     <points num="14290">
    6.                         <p x=0.309469 y=-0.921392 z=0.450065 />
    7.                         <p x=-0.246077 y=0.582705 z=0.060732 />
    8.                         <!-- 14288 weitere Punkte -->
    9.                     </points>
    10.                 </pointSet>
    11.             </geometry>
    12.         </geometries>
    13.     </jvx-model>
    Das könnte JaxB ohne gefrickel umwandeln.

    bye
    TT

  3. #3
    User short Themenstarter

    Registriert seit
    12.04.2014
    Fachbeiträge
    16
    Genannt
    0 Post(s)
    Naja das Problem ist, dass ich die XML als Dateiausgabe von einem anderen Programm bekomme, auf dieses hab ich jedoch keinen Zugriff.
    Also wenn ich nicht vorher per Hand in Java die Datei umschreiben will (und ich denke das wäre blöd) muss ich mit dem Format leben :/

  4. #4
    Frequent User Floppy Disc Avatar von Bleiglanz
    Registriert seit
    31.07.2013
    Fachbeiträge
    761
    Genannt
    99 Post(s)
    JAXB ist doch irgendwie overkill - warum liest du das nicht einfach in ein DOM, oder einfachst mit SAX/Stax aus, wenn die Datei so simpel ist?
    Yeah, well, you know, that's just, like, your opinion, man.

  5. #5
    User short Themenstarter

    Registriert seit
    12.04.2014
    Fachbeiträge
    16
    Genannt
    0 Post(s)
    Na in der Datei stehen selbstverständlich noch eine ganze reihe weiterer Informationen.
    Das ist quasi eine 3D-Mesh Datei mit Informationen á la Wavefront Object datei...

    Zusätzlich kommen noch Vectoren dazu, MatchingSets etc.
    Ich hab das nur auf das simple Beispiel runtergebrochen weil bereits hier der Fehler fliegt.

  6. #6
    Frequent User Floppy Disc Avatar von Bleiglanz
    Registriert seit
    31.07.2013
    Fachbeiträge
    761
    Genannt
    99 Post(s)
    Zitat Zitat von Highchiller Beitrag anzeigen
    Das ist quasi eine 3D-Mesh Datei mit Informationen á la Wavefront Object datei...
    Gibts da kein Schema oder eine DTD dazu?
    Yeah, well, you know, that's just, like, your opinion, man.

  7. #7
    User short Themenstarter

    Registriert seit
    12.04.2014
    Fachbeiträge
    16
    Genannt
    0 Post(s)
    Ja schon, damit hatte ich auch Probleme, daher hatte ich das einfach auskommentiert. Die DTD findest du hier:
    http://www.javaview.de/rsrc/jvx.dtd

  8. #8
    Frequent User Floppy Disc Avatar von Bleiglanz
    Registriert seit
    31.07.2013
    Fachbeiträge
    761
    Genannt
    99 Post(s)
    Verzweiflungstat: Klassen mit JAXB generieren

    mal xjc mit der option -dtd aufrufen? Wird zwar nicht funktionieren, aber einen Versuch ist es Wert...
    Yeah, well, you know, that's just, like, your opinion, man.

  9. #9
    User Megabyte Avatar von Timothy_Truckle
    Registriert seit
    01.08.2013
    Ort
    Wasserkuppe
    Fachbeiträge
    1.329
    Genannt
    85 Post(s)
    Blog-Einträge
    5
    Wenn ich nochmal auf die Fehlermeldung schaue könnte sich noch mal ein Ansatzpunkt ergeben:
    Zitat Zitat von Highchiller Beitrag anzeigen
    Code:
    XmlElementWrapper is only allowed on a collection or array property but [points] is not a collection or array property.
    Und da hat JaxB recht. Die Collection ist nämlich <p>...

    bye
    TT

  10. #10
    User short Themenstarter

    Registriert seit
    12.04.2014
    Fachbeiträge
    16
    Genannt
    0 Post(s)
    Hä? Vielleicht ist die Namenwahl unglücklich gewählt.
    Wieso sollte der XmlElementWrapper denn selber eine Collection/Array sein... es geht doch darum, dass der innere Part eine Collection/Array ist

    Wenn ich dich richtig verstehe, kann ich also eine Struktur wie diese
    Zitat Zitat von Highchiller Beitrag anzeigen
    XML Code:
    1.  
    2.                 <points num="14290">
    3.                     <p>0.309469 -0.921392 0.450065</p>
    4.                     <p>-0.246077 0.582705 0.060732</p>
    5.                     <!-- 14288 weitere Punkte -->
    6.                 </points>
    nicht als
    Java Code:
    1. @XmlElementWrapper( name = "points" )
    2. @XmlElement( name = "p" )
    3. ArrayList<double[]> listofPoints;
    verpacken?

  11. #11
    Frequent User Halbes Megabyte
    Registriert seit
    31.07.2013
    Ort
    Hamburg
    Fachbeiträge
    551
    Genannt
    56 Post(s)
    Blog-Einträge
    2
    Zitat Zitat von Highchiller Beitrag anzeigen
    Wenn ich dich richtig verstehe, kann ich also eine Struktur wie diese [...] nicht als [...] verpacken?
    Ich habe selbst noch nie mit JAXB gearbeitet, aber ich würde sagen: Nein. Grund ist das Attribut "num" im points-Element. Wie soll das mit einem Wrapper "ArrayList" abgedeckt werden? Das wird der Grund sein, warum JAXB sagt, dass es sich bei [points] nicht (nur) um eine Collection handelt.
    Geändert von nillehammer (11.12.2014 um 12:54 Uhr)

  12. #12
    User short Themenstarter

    Registriert seit
    12.04.2014
    Fachbeiträge
    16
    Genannt
    0 Post(s)
    Klingt plausibel. Allerdings erklärt das nicht das Eingangs erwähnte Problem. Da das ja nicht funktionierte hatte ich versucht stupide eine extra Klasse für "points" zu schreiben. Damit kann ich dann das Attribute auslesen. Allerdings funktioniert dann der XmlJavaTypeAdapter nicht...

    Problem verlagert, aber nicht behoben.

+ Antworten Thema als "gelöst" markieren

Direkt antworten Direkt antworten

In welcher Stadt befindet sich "Ground Zero"?

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Ähnliche Themen

  1. typsichere Liste
    Von hamster1989 im Forum Java-Grundlagen
    Antworten: 21
    Letzter Beitrag: 02.06.2014, 14:09
  2. BubbleSort für Abiturvorgabe Liste
    Von groggy im Forum Java-Grundlagen
    Antworten: 45
    Letzter Beitrag: 12.01.2014, 00:17
  3. Opera 16 füllt Formulare aus
    Von L-ectron-X im Forum Software
    Antworten: 0
    Letzter Beitrag: 30.08.2013, 09:17
  4. Liste der JVM-Sprachen
    Von Landei im Forum JVM-Sprachen
    Antworten: 1
    Letzter Beitrag: 31.07.2013, 17:15
  5. Min und Max Wert aus Liste suchen.
    Von Grisu im Forum Dotnet-Forum
    Antworten: 2
    Letzter Beitrag: 06.04.2010, 13:19

Stichworte

Berechtigungen

  • Neue Themen erstellen: Ja
  • Themen beantworten: Ja
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •