2012-04-03 6 views
1

Ich habe ein Projekt eingerichtet, um das Marshalling für ein anderes Projekt zu testen. Marshalling funktioniert. Ich bekomme die korrekte XML-Datei, aber das Unmarshalling funktioniert nicht. Ich erhalte nur den Beziehungsnamen (String). Die Attribute und funktionalen Abhängigkeiten fehlen.JAXB-Unmarshalling funktioniert nicht

EDIT: Hier ist die Quelle: Sourcecode

Bitte nehmen Sie sich einen Blick auf die Klassen:

Main:

public class Main { 

public static void main(String[] args){ 

    Relation db = new Relation(); 

    Attribute a1 = new Attribute("Attribute 1", true, false); 
    Attribute a2 = new Attribute("Attribute 2", false, false); 
    Attribute a3 = new Attribute("Attribute 3", false, true); 

    db.addAttribute(a1); 
    db.addAttribute(a2); 
    db.addAttribute(a3); 

    ArrayList<String> src = new ArrayList<String>(); 
    src.add("Attribute 1"); 

    ArrayList<String> dest = new ArrayList<>(); 
    dest.add("Attribute 2,Attribute 3"); 

    FDs f1 = new FDs(src, dest); 

    db.addFd(f1); 

    exportToXml saver = new exportToXml(); 
    try { 
     saver.SaveDbNow(db); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    //Export again to test output 
    Relation db2 = new Relation(); 

    importFromXml reader = new importFromXml(); 
    try { 
     reader.ReadDbNow(db2); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    try { 
     saver.SaveDbNow2(db2); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 

} 

Relation:

@XmlRootElement(name = "Relation") 
public class Relation { 
@XmlElement(name = "RelName") 
String name; 

@XmlElement(name = "Attribute") 
private ArrayList<Attribute> attrList; 
@XmlElement(name = "FD") 
private ArrayList<FDs> fdsList; 

public Relation() { 
    this.attrList = new ArrayList<>(); 
    this.fdsList = new ArrayList<>(); 
    this.name = "Testname"; 
} 

public Relation(String name, ArrayList<Attribute> attrList, ArrayList<FDs> fdsList) { 
    super(); 
    this.attrList = attrList; 
    this.fdsList = fdsList; 
} 

@XmlTransient 
public ArrayList<Attribute> getAttrList() { 
    return attrList; 
} 

public void setAttrList(ArrayList<Attribute> attrList) { 
    this.attrList = attrList; 
} 

@XmlTransient 
public ArrayList<FDs> getFdsList() { 
    return fdsList; 
} 

public void setFdsList(ArrayList<FDs> fdsList) { 
    this.fdsList = fdsList; 
} 

public void addAttribute(Attribute a) { 
    this.attrList.add(a); 
} 

public void addFd(FDs fd) { 
    this.fdsList.add(fd); 
} 

} 

Attribut:

public class Attribute { 
@XmlElement(name = "Attributename") 
private String name; 
@XmlElement(name = "isPK") 
private boolean isPK; 
@XmlElement(name = "isFK") 
private boolean isFK; 

public Attribute(){ 

} 


public Attribute(String name, boolean isPK, boolean isFK) { 
    super(); 
    this.name = name; 
    this.isPK = isPK; 
    this.isFK = isFK; 
} 

@XmlTransient 
public String getName() { 
    return name; 
} 
public void setName(String name) { 
    this.name = name; 
} 
@XmlTransient 
public boolean isPK() { 
    return isPK; 
} 

public void setPK(boolean isPK) { 
    this.isPK = isPK; 
} 

@XmlTransient 
public boolean isFK() { 
    return isFK; 
} 
public void setFK(boolean isFK) { 
    this.isFK = isFK; 
} 
} 

FD:

public class FDs { 
@XmlElement(name = "Source") 
private ArrayList<String> src; 
@XmlElement(name = "Destination") 
private ArrayList<String> dest; 

public FDs(){ 

} 

public FDs(ArrayList<String> src, ArrayList<String> dest) { 
    super(); 
    this.src = src; 
    this.dest = dest; 
} 

@XmlTransient 
public ArrayList<String> getSrc() { 
    return src; 
} 
public void setSrc(ArrayList<String> src) { 
    this.src = src; 
} 

@XmlTransient 
public ArrayList<String> getDest() { 
    return dest; 
} 
public void setDest(ArrayList<String> dest) { 
    this.dest = dest; 
} 
} 

Export:

public class exportToXml { 

public void SaveDbNow(Object saveMe) throws Exception { 
    JAXB.marshal(saveMe, new File("test.xml")); 
} 

public void SaveDbNow2(Object saveMe) throws Exception { 
    JAXB.marshal(saveMe, new File("test2.xml")); 
} 
} 

Import:

public class importFromXml { 

public void ReadDbNow(Object readMe) throws Exception { 
    readMe = JAXB.unmarshal(new FileInputStream("test.xml"), Relation.class); 
} 
} 

Vielen Dank im Voraus!

EDIT: Output1:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Relation> 
<RelName>Testname</RelName> 
<Attribute> 
    <Attributename>Attribute 1</Attributename> 
    <isPK>true</isPK> 
    <isFK>false</isFK> 
</Attribute> 
<Attribute> 
    <Attributename>Attribute 2</Attributename> 
    <isPK>false</isPK> 
    <isFK>false</isFK> 
</Attribute> 
<Attribute> 
    <Attributename>Attribute 3</Attributename> 
    <isPK>false</isPK> 
    <isFK>true</isFK> 
</Attribute> 
<FD> 
    <Source>Attribute 1</Source> 
    <Destination>Attribute 2,Attribute 3</Destination> 
</FD> 

Output2:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Relation> 
<RelName>Testname</RelName> 
</Relation> 
+1

Sie mischen Getter und Feldern. Entscheiden Sie sich für einen Accessor-Typ, z. B. "@XmlAccessorType (XmlAccessType.FIELD)" -Anmerkung für Klassen. –

+1

Der folgende Artikel wird mit dem von @GrzegorzGrzybek gegeben Vorschlag helfen: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html –

+0

Dank @GrzegorzGrzybek und @BlaiseDoughan! Ich werde einen Blick darauf werfen –

Antwort

1

Erklärung für Aktuelles Verhalten

In der Main Klasse instanziiert Sie eine neue Instanz von Relation der Konstruktor füllt die name Eigenschaft "Testname". Nichts anderes ist jemals in der Instanz Relation eingetragen. Aus diesem Grund sehen Sie die XML-Ausgabe, die Sie sind.

// Export again to test output 
    Relation db2 = new Relation(); 

    importFromXml reader = new importFromXml(); 
    try { 
     reader.ReadDbNow(db2); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    try { 
     saver.SaveDbNow2(db2); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

mögliche Lösung

Ändern der ReadDbNow Methode auf der importFromXml Klasse die Instanz von Relation zurückzugeben, die es entordnet.

import java.io.FileInputStream; 
import javax.xml.bind.JAXB; 

public class importFromXml { 

    public Relation ReadDbNow() throws Exception { 
     return JAXB 
       .unmarshal(new FileInputStream("test.xml"), Relation.class); 
    } 
} 

Im Main Klasse Ihren Code ändern, Folgendes zu tun:

// Export again to test output 
    Relation db2 = null; 

    importFromXml reader = new importFromXml(); 
    try { 
     db2 = reader.ReadDbNow(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    try { 
     saver.SaveDbNow2(db2); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
+1

Vielen Dank! Ich dachte, der Fehler liegt bei den Arraylisten. Ich habe viel Zeit damit verbracht, den Fehler am falschen Ende zu suchen! –

0

Sie benötigen Klassen mit @XmlRootElement zu annotieren. Z.B. Attribute hat nicht die Anmerkung

+0

Sorry funktioniert nicht. Aktualisierter 1. Post Hinzugefügt die 2 xml Dateien –

+0

Haben Sie Setter Methoden für jede Klasse proeprty? – fmucar