2010-02-26 1 views
3

От http://weblogs.java.net/blog/2005/04/22/xmladapter-jaxb-ri-eaКак избавиться от имени элемента элемента при использовании XmlJavaTypeAdapter для java.util.Map в JAXB

import java.io.StringReader; 
import java.io.StringWriter; 
import java.util.HashMap; 
import java.util.Map; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

public class BrochureOriginal { 
    @XmlRootElement(name = "brochure") 
    static class Brochure { 
    @XmlJavaTypeAdapter(CourseListAdapter.class) 
    @XmlElement(name = "courses") 
    Map<String, Course> coursesByIdMap; 
    } 

    static class Course { 
    @XmlAttribute 
    String id; 

    @XmlElement 
    String name; 

    } 

    static class CourseListAdapter extends XmlAdapter<Course[], Map<String, Course>> { 
    public Course[] marshal(Map<String, Course> value) { 
     return value.values().toArray(new Course[value.size()]); 
    } 

    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; 
    } 

    } 

    private static <T> String convertObjectToXml(Class<T> clazz, T instance) { 
    try { 
     JAXBContext jc = JAXBContext.newInstance(clazz); 
     Marshaller m = jc.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     StringWriter sw = new StringWriter(); 
     m.marshal(instance, sw); 
     return sw.toString(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
    } 

    @SuppressWarnings("unchecked") 
    private static <T> T convertXmlToObject(Class<T> clazz, String xml) { 
    try { 
     JAXBContext jc = JAXBContext.newInstance(clazz); 
     Unmarshaller m = jc.createUnmarshaller(); 
     StringReader sr = new StringReader(xml); 
     T instance = (T) m.unmarshal(sr); 
     return instance; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
    } 

    public static void main(String[] args) { 

    Brochure b = new Brochure(); 
    Course c = null; 

    // 1st course 
    c = new Course(); 
    c.id = "cs501"; 
    c.name = "Software Engineering"; 
    b.coursesByIdMap = new HashMap<String, Course>(); 
    b.coursesByIdMap.put(c.id, c); 

    // 2nd course 
    c = new Course(); 
    c.id = "cs519"; 
    c.name = "Network Security"; 
    b.coursesByIdMap.put(c.id, c); 

    Brochure source = b; 
    String sourceDisplay = getDisplay(source); 
    String xml = convertObjectToXml(Brochure.class, b); 
    System.out.println(sourceDisplay); 
    System.out.println(xml); 

    Brochure restored = convertXmlToObject(Brochure.class, xml); 
    String restoredDisplay = getDisplay(restored); 
    System.out.println(restoredDisplay); 

    } 

    private static String getDisplay(Brochure b) { 
    String nl = System.getProperty("line.separator"); 
    StringBuilder sb = new StringBuilder(); 
    sb.append(nl + "Brochure"); 
    for (Map.Entry<String, Course> entry : b.coursesByIdMap.entrySet()) { 
     Course course = entry.getValue(); 
     sb.append(nl + " coursesByIdMap.entry"); 
     sb.append(nl + " key: String(" + entry.getKey() + ")"); 
     sb.append(nl + " value: Course(id=" + course.id + ", name=" + course.name + ")"); 
    } 
    return sb.toString(); 
    } 

} 

Это выход ...

Brochure 
    coursesByIdMap.entry 
    key: String(cs519) 
    value: Course(id=cs519, name=Network Security) 
    coursesByIdMap.entry 
    key: String(cs501) 
    value: Course(id=cs501, name=Software Engineering) 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<brochure> 
    <courses> 
     <item id="cs519"> 
      <name>Network Security</name> 
     </item> 
     <item id="cs501"> 
      <name>Software Engineering</name> 
     </item> 
    </courses> 
</brochure> 


Brochure 
    coursesByIdMap.entry 
    key: String(cs519) 
    value: Course(id=cs519, name=Network Security) 
    coursesByIdMap.entry 
    key: String(cs501) 
    value: Course(id=cs501, name=Software Engineering) 

я что-то вроде желания ...

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<brochure> 
    <courses> 
     <course id="cs519"> 
      <name>Network Security</name> 
     </course> 
     <course id="cs501"> 
      <name>Software Engineering</name> 
     </course> 
    </courses> 
</brochure> 

Возможно, я не могу найти способ избавиться от этого элемента.

Из ресурсов ответа, вот способ сделать это с помощью предмета костыля.

import java.io.StringReader; 
import java.io.StringWriter; 
import java.util.HashMap; 
import java.util.Map; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

public class BrochureTest { 
    @XmlRootElement(name = "brochure") 
    static class Brochure { 
    @XmlJavaTypeAdapter(CourseListAdapter.class) 
    @XmlElement(name = "courses") 
    Map<String, Course> coursesByIdMap; 
    } 

    static class Course { 
    @XmlAttribute 
    String id; 

    @XmlElement 
    String name; 

    } 

    static class CourseListAdapter extends XmlAdapter<CoursesJaxbCrutch, Map<String, Course>> { 
    public CoursesJaxbCrutch marshal(Map<String, Course> value) { 
     CoursesJaxbCrutch courses = new CoursesJaxbCrutch(); 
     courses.courses = value.values().toArray(new Course[value.size()]); 
     return courses; 
    } 

    public Map<String, Course> unmarshal(CoursesJaxbCrutch value) { 
     Map<String, Course> r = new HashMap<String, Course>(); 
     for (Course c : value.courses) 
     r.put(c.id, c); 
     return r; 
    } 

    } 

    private static class CoursesJaxbCrutch { 
    @XmlElement(name = "course") 
    private Course[] courses; 
    } 

    private static <T> String convertObjectToXml(Class<T> clazz, T instance) { 
    try { 
     JAXBContext jc = JAXBContext.newInstance(clazz); 
     Marshaller m = jc.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     StringWriter sw = new StringWriter(); 
     m.marshal(instance, sw); 
     return sw.toString(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
    } 

    @SuppressWarnings("unchecked") 
    private static <T> T convertXmlToObject(Class<T> clazz, String xml) { 
    try { 
     JAXBContext jc = JAXBContext.newInstance(clazz); 
     Unmarshaller m = jc.createUnmarshaller(); 
     StringReader sr = new StringReader(xml); 
     T instance = (T) m.unmarshal(sr); 
     return instance; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
    } 

    public static void main(String[] args) { 

     Brochure b = new Brochure(); 
    Course c = null; 

    // 1st course 
    c = new Course(); 
    c.id = "cs501"; 
    c.name = "Software Engineering"; 
    b.coursesByIdMap = new HashMap<String, Course>(); 
    b.coursesByIdMap.put(c.id, c); 

    // 2nd course 
    c = new Course(); 
    c.id = "cs519"; 
    c.name = "Network Security"; 
    b.coursesByIdMap.put(c.id, c); 

    Brochure source = b; 
    String sourceDisplay = getDisplay(source); 
    String xml = convertObjectToXml(Brochure.class, b); 
    System.out.println(sourceDisplay); 
    System.out.println(xml); 

    Brochure restored = convertXmlToObject(Brochure.class, xml); 
    String restoredDisplay = getDisplay(restored); 
    System.out.println(restoredDisplay); 

    } 

    private static String getDisplay(Brochure b) { 
    String nl = System.getProperty("line.separator"); 
    StringBuilder sb = new StringBuilder(); 
    sb.append(nl + "Brochure"); 
    for (Map.Entry<String, Course> entry : b.coursesByIdMap.entrySet()) { 
     Course course = entry.getValue(); 
     sb.append(nl + " coursesByIdMap.entry"); 
     sb.append(nl + " key: String(" + entry.getKey() + ")"); 
     sb.append(nl + " value: Course(id=" + course.id + ", name=" + course.name + ")"); 
    } 
    return sb.toString(); 
    } 

} 

Выход:

Brochure 
    coursesByIdMap.entry 
    key: String(cs519) 
    value: Course(id=cs519, name=Network Security) 
    coursesByIdMap.entry 
    key: String(cs501) 
    value: Course(id=cs501, name=Software Engineering) 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<brochure> 
    <courses> 
     <course id="cs519"> 
      <name>Network Security</name> 
     </course> 
     <course id="cs501"> 
      <name>Software Engineering</name> 
     </course> 
    </courses> 
</brochure> 


Brochure 
    coursesByIdMap.entry 
    key: String(cs519) 
    value: Course(id=cs519, name=Network Security) 
    coursesByIdMap.entry 
    key: String(cs501) 
    value: Course(id=cs501, name=Software Engineering) 

Так что теперь, как вы можете сделать это без этого костыля объекта?

+0

См. http://stackoverflow.com/questions/81 8327/jaxb-how-should-i-marshal-complex-inested-data-структуры – skaffman

+0

Метод xmlize - это еще один костыль ... Я сейчас иду с текущим объектом костыля. – TJR

ответ

0

Пример из вашей ссылки не работает - вот две ссылки, которые обсуждают, как вы можете получить результаты, которые вы ищете:

http://old.nabble.com/XmlJavaTypeAdapter-help-td19127284.html

http://forums.java.net/jive/message.jspa?messageID=267376

Обратите внимание, что есть небольшая проблема с вашим методом main(), я выделил исправление:

public static void main(String[] args) { 
     Brochure b = new Brochure(); 
     Course c = new Course(); 
     c.id = "cs501"; 
     c.name = "Software Engineering"; 
     b.courses = new HashMap<String, Course>(); 
     b.courses.put(c.id, c); 
     c = new Course() // You need to add this 
     c.id = "cs519"; 
     c.name = "Network Security"; 
     b.courses.put(c.id, c); 

     System.out.println(convertObjectToXml(Brochure.class, b)); 

} 
+0

Я обновил вопрос, чтобы исправить ошибку. Благодаря! – TJR

Смежные вопросы