Thanks for the explanation. It makes sense now. I also found that it is
possible to achieve the same result (with course elements as direct children
of brochure) by not using the XmlAdapter itself and instead annotating a
getter method that returns a Course[] array (made of the map contents) like
this:
@XmlElement(name = "course")
private Course[] getCourses() {
Course[] result = new Course[courses.size()];
int i = 0;
for (String id : courses.keySet())
result[i++] = courses.get(id);
return result;
}
Regards,
Murali
Wolfgang Laun-2 wrote:
>
> The annotation on Brochure.courses says that you want to have a
> sub-element <course>. Note that nothing here indicates that this
> element would have - expressed in XML Schema language -
> maxOccurs="unbounded". So there is going to be a single <course>
> element. The Course[] that's going to be used for the contents
> of <course> needs some intermediary level for separating its
> elements - that's why you have the <item>s. In short: I don't think
> you're doing anything wrong.
>
> If you do want an XML structure without the additional XML level,
> you'll have to let JAXB see a collection, to be marshalled as
> Brochure's sub-element, e.g.:
>
> @XmlElement(name="courses")
> Collection<Course> courses;
>
> Another option would be to adapt Brochure (and not its field). This
> doesn't work for Brochure being a root element, but given this
> additional class
>
> @XmlRootElement(name="college")
> public class College {
> @XmlElement
> public Brochure brochure;
>
> public College(){}
> public College( Brochure b ){
> brochure = b;
> }
> }
>
> you can write Brochure.java as
>
> @XmlJavaTypeAdapter(BrochureAdapter.class)
> public class Brochure {
> Map<String,Course> courses;
> public Brochure() {
> courses = new HashMap<String, Course>();
> }
> }
>
> BrochureAdapter.java maps a Brochure to a class Courses which informs
> JAXB about the desired XML structure:
>
> public class Courses {
> @XmlElement(name="course")
> public Course[] carray;
> }
>
> public class BrochureAdapter
> extends XmlAdapter<Courses,Brochure> {
>
> public Brochure unmarshal( Courses value ) {
> Brochure b = new Brochure();
> for( Course c : value.carray )
> b.courses.put( c.id, c );
> return b;
> }
>
> public Courses marshal( Brochure b ) {
> Courses courses = new Courses();
> Collection<Course> c = b.courses.values();
> courses.carray = c.toArray(new Course[c.size()]);
> return courses;
> }
> }
>
> And this is what you'll get now
>
> <college>
> <brochure>
> <course id="c1">
> <name>Course 1</name>
> </course>
> <course id="c0">
> <name>Course 0</name>
> </course>
> </brochure>
> </college>
>
> HTH,
> Wolfgang
>
>
> On Sun, Aug 24, 2008 at 4:39 AM, murakris <cme_mk_at_yahoo.com> wrote:
>>
>> Hi, I'm trying to follow the XmlAdapter example in Koshuke's blog here:
>> http://weblogs.java.net/blog/kohsuke/archive/2005/04/xmladapter_in_j.html
>>
>> and when I try to marshall the Brochure class, it results in xml output
>> like
>> this:
>> <brochure>
>> <course>
>> <item id="c0">
>> <name>Course 0</name>
>> </item>
>> <item id="c1">
>> <name>Course 1</name>
>> </item>
>> </course>
>> </brochure>
>>
>> instead of
>> <brochure>
>> <course id="c0">
>> <name>Course 0</name>
>> </item>
>> <course id="c1">
>> <name>Course 1</name>
>> </item>
>> </brochure>
>>
>> Can you please help me understand what I'm doing wrong? Below is the rest
>> of
>> the code:
>>
>> Brochure.java:
>> @XmlRootElement(name="brochure")
>> public class Brochure {
>> @XmlJavaTypeAdapter(CourseListAdapter.class)
>> @XmlElement(name="course")
>> Map<String,Course> courses;
>>
>> public Brochure() {
>> courses = new HashMap<String, Course>();
>> }
>> }
>>
>> Course.java
>> public class Course {
>> @XmlAttribute
>> String id;
>> @XmlElement
>> String name;
>> }
>>
>> CourseListAdapter
>> public class CourseListAdapter extends XmlAdapter<Course[],
>> Map<String,Course>> {
>
>> public Map<String,Course> unmarshal( Course[] value ) {
>> Map<String,Course> r = new HashMap<String,Course>();
>> for( Course c : value )
>> r.put(c.id,c);
>> return r;
>> }
>> public Course[] marshal( Map<String,Course> value ) {
>> return value.values().toArray(new Course[value.size()]);
>> }
>>
>> Test class:
>> public class Main {
>>
>> @Test public void test() throws Exception {
>> JAXBContext jc = JAXBContext.newInstance(Brochure.class);
>> Marshaller m = jc.createMarshaller();
>> m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
>>
>> Brochure b = new Brochure();
>> for (int i=0; i<2; i++) {
>> Course c = getCourse(i);
>> b.courses.put(c.id, c);
>> }
>>
>> m.marshal(b, System.out);
>>
>> }
>>
>> public Course getCourse(int i) {
>> Course c1 = new Course();
>> c1.id="c" + i;
>> c1.name="Course " + i;
>> return c1;
>> }
>> }
>>
>> }
>>
>> Thanks in advance!
>> Murali
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>
>
--
View this message in context: http://www.nabble.com/XmlJavaTypeAdapter-help-tp19127284p19132090.html
Sent from the java.net - jaxb users mailing list archive at Nabble.com.