# JAXB @XMLID und @XMLIDREF, wie Daten hinzufügen



## mem (5. Dez 2014)

Hallo ich möchte mit JAXB meine Daten in XML speichern. Ich habe allerdings keine Ahnung, wie ich nur Referenzen speichern kann. Ich habe schon lange gesucht und nichts gefunden. Wenn ich das mit @XMLID und @XMLIDREF versuche, erhalte ich zwar die Schlüssel, aber die Objekte, die die Daten enthalten sind nirgendwo zu finden. Im Beispiel unten sind die IDs der Personen, aber nicht die zugehörigen Personen Objekte. Wie kann ich die zusätzlich speichern?


```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<company>
    <companyNo>c101</companyNo>
    <name>JAXB Company1</name>
    <employee>
        <person>p101</person>
        <person>p202</person>
        <person>p303</person>
    </employee>
</company>
```


```
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

	@XmlID
	private String pId;
	private String name;
}
```


```
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Company {

	private String companyNo;
	private String name;
	
	@XmlElementWrapper(name="employee")
	@XmlElement(name="person")
	@XmlIDREF
	private List<Person> employee;
}
```


```
public class CompanyExport {

	public static void main(String[] args) throws FileNotFoundException, IOException {

		List<Person> employee = new ArrayList<Person>();
		
		Person p1 = new Person();
		p1.setName("Name1");
		p1.setPId("p101");
		employee.add(p1);
		
		Person p2 = new Person();
		p2.setName("Name2");
		p2.setPId("p202");
		employee.add(p2);
		
		Person p3 = new Person();
		p3.setName("Name3");
		p3.setPId("p303");
		employee.add(p3);
		
		Company c = new Company();
		c.setEmployee(employee);
		c.setCompanyNo("c101");
		c.setName("JAXB Company1");
		
		try (FileOutputStream out = new FileOutputStream(new File("CompanyExport.xml"))){
			JAXBContext context = JAXBContext.newInstance(Company.class);
			Marshaller jMarshall = context.createMarshaller();
			jMarshall.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			jMarshall.marshal(c, out);
		} catch (JAXBException e) {
			e.printStackTrace();
		}		
	}
}
```


----------



## CptSocket (5. Dez 2014)

Hoi mem

Das Problem ist, dass die Personen ausschliesslich mit @XmlIDREF annotiert in der Datenstruktur vorhanden sind. Dies führt dazu, dass nur die Referenzen auf die Personen, nicht aber die Personen an sich im XML enthalten sind.

=> Damit auch die Personen ins XML geschrieben werden, müssten sie in der zu serialisierenden Datenstruktur irgendwo auch normal / ohne @XmlIDREF enthalten sein.

Siehe z.B. folgendes Beispiel:


```
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Artikel {
	@XmlID
	@XmlAttribute
	private String id;

	public String getId() {
		return id;
	}

	public void setId(String aId) {
		id = aId;
	}
}
```


```
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Bestellung {

	@XmlID
	@XmlAttribute
	private String id;

	@XmlIDREF
	@XmlAttribute
	private Artikel artikel;

	public String getId() {
		return id;
	}

	public void setId(String aId) {
		id = aId;
	}

	public Artikel getArtikel() {
		return artikel;
	}

	public void setArtikel(Artikel aArtikel) {
		artikel = aArtikel;
	}
}
```


```
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Daten {
	@XmlElement
	private List<Artikel> artikel;

	@XmlElement
	private List<Bestellung> bestellungen;

	public List<Artikel> getArtikel() {
		return artikel;
	}

	public void setArtikel(List<Artikel> aArtikel) {
		artikel = aArtikel;
	}

	public List<Bestellung> getBestellungen() {
		return bestellungen;
	}

	public void setBestellungen(List<Bestellung> aBestellungen) {
		bestellungen = aBestellungen;
	}
}
```


```
public class Main {
	public static void main(String[] args) throws Exception {
		Artikel artikel1 = new Artikel();
		artikel1.setId("1");

		Artikel artikel2 = new Artikel();
		artikel2.setId("2");

		Bestellung bestellung1 = new Bestellung();
		bestellung1.setId("11");
		bestellung1.setArtikel(artikel1);

		Bestellung bestellung2 = new Bestellung();
		bestellung2.setId("22");
		bestellung2.setArtikel(artikel2);

		List<Artikel> alleArtikel = new ArrayList<>();
		alleArtikel.add(artikel1);
		alleArtikel.add(artikel2);

		List<Bestellung> bestellungen = new ArrayList<>();
		bestellungen.add(bestellung1);
		bestellungen.add(bestellung2);

		Daten daten = new Daten();
		daten.setArtikel(alleArtikel);
		daten.setBestellungen(bestellungen);

		FileOutputStream out = new FileOutputStream(new File("test.xml"));
		JAXBContext context = JAXBContext.newInstance(Daten.class);
		Marshaller jMarshall = context.createMarshaller();
		jMarshall.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		jMarshall.marshal(daten, out);
	}
}
```

Dies führt zu folgendem XML:

```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<daten>
    <artikel id="1"/>
    <artikel id="2"/>
    <bestellungen id="11" artikel="1"/>
    <bestellungen id="22" artikel="2"/>
</daten>
```


Freundliche Grüsse
CptSocket


----------



## mem (6. Dez 2014)

Hey, super! Vielen Dank für die Antwort. Endlich funktioniert es so, wie es soll 

Habe jetzt eine Klasse Data eingefügt und bei Person die ID als Attribut gespeichert.


```
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {

	@XmlID
	@XmlAttribute
	private String pId;
	@XmlElement
	private String name;
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Company {

	@XmlAttribute
	private String companyNo;
	@XmlElement
	private String name;
	
	@XmlElementWrapper(name="employee")
	@XmlElement(name="person")
	@XmlIDREF
	private List<Person> employee;
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Data {
	
	private List<Company>companies;
	
	private List<Person>persons;

	public List<Company> getCompanies() {
		return companies;
	}
}
```

Diese dann exportiert und es funktioniert.


```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
    <companies companyNo="c202">
        <name>JAXB Company2</name>
        <employee>
            <person>p101</person>
            <person>p202</person>
            <person>p303</person>
        </employee>
    </companies>
    <companies>
        <employee>
            <person>p101</person>
            <person>p202</person>
            <person>p303</person>
        </employee>
    </companies>
    <persons pId="p101">
        <name>Name1</name>
    </persons>
    <persons pId="p202">
        <name>Name2</name>
    </persons>
    <persons pId="p303">
        <name>Name3</name>
    </persons>
</data>
```


----------

