Staying within JAXB
how would I refactor MyNote
so that it conforms to:
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
Which is well formed but not valid, to my understanding. Current output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyNotes>
<Note>
<note>XY3Z1RGEO9W79LALCS</note>
<to>LJAY9RNMUGGENGNND9</to>
<from>GOVSHVZ3GJWC864L7X</from>
<heading>EX6LGVE5LGY4A6B9SK</heading>
<body>L95WYQNMEU1MFDRBG4</body>
</Note>
</MyNotes>
which is too flat, rather than nested as the example.
I believe this makes note
the root
element, with other elements being children
nodes to note
if I'm using correct terminology.
The MyNote
class:
package net.bounceme.dur.jaxb.hello.world;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(propOrder = {"note", "to", "from", "heading", "body"})
@XmlRootElement(name = "note")
public class MyNote {
private String note;
private String to;
private String from;
private String heading;
private String body;
public String getNote() {
return note;
}
@XmlElement(name = "note")
public void setNote(String note) {
this.note = note;
}
public String getTo() {
return to;
}
@XmlElement(name = "to")
public void setTo(String to) {
this.to = to;
}
public String getFrom() {
return from;
}
@XmlElement(name = "from")
public void setFrom(String from) {
this.from = from;
}
public String getHeading() {
return heading;
}
@XmlElement(name = "heading")
public void setHeading(String heading) {
this.heading = heading;
}
public String getBody() {
return body;
}
@XmlElement(name = "body")
public void setBody(String body) {
this.body = body;
}
@Override
public String toString() {
return note + to + from + heading + body;
}
}
The MyNotes
class:
package net.bounceme.dur.jaxb.hello.world;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "MyNotes")
public class MyNotes {
private static final Logger LOG = Logger.getLogger(MyNotes.class.getName());
private List<MyNote> myNotes = new ArrayList<>();
public MyNotes() {
}
public List<MyNote> getMyNotes() {
LOG.info(myNotes.toString());
return myNotes;
}
@XmlElement(name = "Note")
public void setMyNotes(List<MyNote> myNotes) {
LOG.info(myNotes.toString());
this.myNotes = myNotes;
}
public void add(MyNote myNote) {
LOG.info(myNote.toString());
myNotes.add(myNote);
}
@Override
public String toString() {
StringBuffer str = new StringBuffer();
for (MyNote note : this.myNotes) {
str.append(note.toString());
}
return str.toString();
}
}
exercising the MyNote
and MyNotes
classes:
public MyNotes unmarshallMyNotesFromFile(URI uri) throws Exception {
File file = new File(uri);
JAXBContext jaxbContext = JAXBContext.newInstance(MyNotes.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
MyNotes myNotes = (MyNotes) jaxbUnmarshaller.unmarshal(file);
return myNotes;
}
public void marshallMyNotesAndWriteToFile(MyNotes notes, URI uri) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(MyNotes.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(notes, new File(uri));
jaxbMarshaller.marshal(notes, System.out);
}
I'm looking to grab this xml
through the web; first need to match the structure to the example.
You are very close. You need to change how you name your xmlElement for myNotes in MyNotes class. Also MyNote should not have a note field itself (according to your desired xml). Your edited classes would look like this (I also removed the logging statements for my convenience):
and MyNotes: