如何使用JAXB编组多个对象?

我正在尝试编组多个对象,例如通过setBookslst() Book添加到BookLists 。 我开始使用这个JAXBContext设置:

 jaxbContext = JAXBContext.newInstance(BookLists.class); 

  jaxbMarshaller.marshal(lists, result); 

但是,我得到了以下运行时exception:

javax.xml.bind.JAXBException:com.jaxb.example.marshall.Book或其任何超类都知道此上下文]

我的类型定义如下。

书: –

 @XmlRootElement(name="book") public class Book { private String title; private int year; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } } 

书目清单: –

 @XmlRootElement(name="lists") public class BookLists { List bookslst; public List getBookslst() { return bookslst; } public void setBookslst(List bookslst) { this.bookslst = bookslst; } } 

马歇尔代码: –

 Book book; BookLists lists=new BookLists(); List lst=new ArrayList(); book = new Book(); book.setTitle("Book title"); book.setYear(2010); lst.add(book); book = new Book(); book.setTitle("Book title1"); book.setYear(2011); lst.add(book); lists.setBookslst(lst); JAXBContext jaxbContext; try { jaxbContext = JAXBContext.newInstance(BookLists.class); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); StringWriter result = new StringWriter(); jaxbMarshaller.marshal(lists, result); String xml = result.toString(); System.out.println(xml); } catch (JAXBException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

我正在尝试放置@XMLSeeAlso注释(参考: – JAXBexception:此上下文不知道类 )。 我的版本中没有此注释。

默认情况下,JAXB(JSR-222)实现检查公共访问器方法。 您可以在get / set方法中的List上添加Book参数。

 public List getBookslst() { return bookslst; } public void setBookslst(List bookslst) { this.bookslst = bookslst; } 

或者,您可以使用@XmlElement批注指定属性的类型:

 @XmlElement(type=Book.class) public List getBookslst() { return bookslst; } 

您还可以指定JAXB实现内省字段而不是属性:

 @XmlRootElement(name="lists") @XmlAccessorType(XmlAccessType.FIELD) public class BookLists { List bookslst; } 

UPDATE

有没有其他方法可以在Marshallar.Marshall中添加List而不是BookList?

您可以创建一个利用@XmlAnyElement(lax=true)注释的通用List包装器对象(请参阅: http : @XmlAnyElement(lax=true) )。 然后它冷处理用@XmlRootElement注释的任何内容的List

清单

 package forum12323397; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.*; @XmlRootElement public class Lists { private List values = new ArrayList(); @XmlAnyElement(lax=true) public List getValues() { return values; } } 

演示

 package forum12323397; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Lists.class, Book.class); Lists lists = new Lists(); Book book1 = new Book(); book1.setTitle("A Book"); book1.setYear(2001); lists.getValues().add(book1); Book book2 = new Book(); book2.setTitle("Another Book"); book2.setYear(2007); lists.getValues().add(book2); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(lists, System.out); } } 

产量

    A Book 2001   Another Book 2007   

使用

 List lst=new ArrayList(); 

代替 :

 List lst=new ArrayList(); 

同时定义BoolList如下:

 @XmlRootElement(name="lists") public class BookLists { List bookslst; public List getBookslst() { return bookslst; } public void setBookslst(List bookslst) { this.bookslst = bookslst; } } 

尝试将这两个类添加到JAXBContext.newInstance调用中。

 JAXBContext.newInstance(BookLists.class, Book.class); 

使用你的课程这是有效的:

 public static void main(String [] args) throws JAXBException { BookLists books = new BookLists(); String [] titles = {"To Kill a Mockingbird", "Twelve Angry Men", "Are You My Mother", "Green Eggs And Ham"}; List list = new ArrayList(); for (String title : titles) { Book book = new Book(); book.setTitle(title); list.add(book); } books.setBookslst(list); JAXBContext jc = JAXBContext.newInstance(BookLists.class, Book.class); Marshaller nm = jc.createMarshaller(); nm.setProperty("jaxb.formatted.output", true); nm.marshal(books, System.out); } 

输出:

    To Kill a Mockingbird 0   Twelve Angry Men 0   Are You My Mother 0   Green Eggs And Ham 0   

将注释@XmlSeeAlso(value = {Book.class})添加到BookList类。 应该现在工作。

我有一个工作示例:

1)XML:

     Neil Strauss The Game Harpercollins 978-0060554736   Charlotte Roche Feuchtgebiete Dumont Buchverlag 978-3832180577   Frankfurt Airport Fraport Bookstore  

2)Java类:

书店

 package jaxbtest; import java.util.ArrayList; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name="bookstore") // (namespace = "de.vogella.xml.jaxb.model", name="bookstore") public class Bookstore { // XmLElementWrapper generates a wrapper element around XML representation @XmlElementWrapper(name = "bookList") // XmlElement sets the name of the entities @XmlElement(name = "book") private ArrayList bookList; private String name; private String location; public void setBookList(ArrayList bookList) { this.bookList = bookList; } public ArrayList getBooksList() { return bookList; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } } 

3)预订

 package jaxbtest; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement(name = "book") // If you want you can define the order in which the fields are written // Optional @XmlType(propOrder = { "author", "name", "publisher", "isbn" }) public class Book { private String name; private String author; private String publisher; private String isbn; // If you like the variable name, eg "name", you can easily change this // name for your XML-Output: @XmlElement(name = "title") public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPublisher() { return publisher; } public void setPublisher(String publisher) { this.publisher = publisher; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } } 

4)主要

 package jaxbtest; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class BookMain { private static final String BOOKSTORE_XML = "./bookstore-jaxb.xml"; public static void main(String[] args) throws JAXBException, IOException { ArrayList bookList = new ArrayList(); // create books Book book1 = new Book(); book1.setIsbn("978-0060554736"); book1.setName("The Game"); book1.setAuthor("Neil Strauss"); book1.setPublisher("Harpercollins"); bookList.add(book1); Book book2 = new Book(); book2.setIsbn("978-3832180577"); book2.setName("Feuchtgebiete"); book2.setAuthor("Charlotte Roche"); book2.setPublisher("Dumont Buchverlag"); bookList.add(book2); // create bookstore, assigning book Bookstore bookstore = new Bookstore(); bookstore.setName("Fraport Bookstore"); bookstore.setLocation("Frankfurt Airport"); bookstore.setBookList(bookList); // create JAXB context and instantiate marshaller JAXBContext context = JAXBContext.newInstance(Bookstore.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Write to System.out m.marshal(bookstore, System.out); // Write to File m.marshal(bookstore, new File(BOOKSTORE_XML)); // get variables from our xml file, created before System.out.println(); System.out.println("Output from our XML File: "); Unmarshaller um = context.createUnmarshaller(); Bookstore bookstore2 = (Bookstore) um.unmarshal(new FileReader(BOOKSTORE_XML)); ArrayList list = bookstore2.getBooksList(); for (Book book : list) { System.out.println("Book: " + book.getName() + " from " + book.getAuthor()); } /* String xmlStr = readFileToString(BOOKSTORE_XML); Bookstore bookstore = getPartial3(Bookstore.class ,xmlStr); for (Book b : bookstore.getBooksList()) System.out.println(b.getName()+ " ---- " + b.getAuthor() ); xmlStr = readFileToString("./listApplianceOfferings.xml"); ApplianceList bookstore1 = getPartial3(ApplianceList.class ,xmlStr); for (Appliance b : bookstore1.getBooksList()) System.out.println(b.getName() + " ---- " + b.getDescription() ); */ //88888 // String xmlStr = readFileToString("./listStorageOfferings.xml"); // StorageOfferings storageOfferingsList = jaxbXmlString2Class(StorageOfferings.class ,xmlStr); StorageOfferings storageOfferingsList = jaxbXmlFile2Class(StorageOfferings.class ,"./listStorageOfferings.xml"); for (StorageOffering s : storageOfferingsList.getStorageOfferingList() ) System.out.println("8888--> "+ s.getName() + " ---- " + s.getId() ); //99999 }//main private static void getPartial() { // get variables from our xml file, created before System.out.println(); System.out.println("Output from our XML File: "); Unmarshaller um; try { JAXBContext context = JAXBContext.newInstance(Bookstore.class);; um = context.createUnmarshaller(); // um.setEventHandler(new DefaultValidationEventHandler()); FileReader fileReader = new FileReader(BOOKSTORE_XML); Bookstore bookstore = (Bookstore) um.unmarshal(fileReader ); ArrayList list = bookstore.getBooksList(); for (Book book : list) { System.out.println("Book: " + book.getName() + " from " + book.getAuthor()); } } catch (Exception e) { e.printStackTrace(); } } private static void getPartial1() { // get variables from our xml file, created before System.out.println(); System.out.println("Output from our XML File: "); Unmarshaller um; try { JAXBContext context = JAXBContext.newInstance(ApplianceList.class);; um = context.createUnmarshaller(); // um.setEventHandler(new DefaultValidationEventHandler()); FileReader fileReader = new FileReader("./listApplianceOfferings.xml"); ApplianceList alist = (ApplianceList) um.unmarshal(fileReader ); ArrayList list = alist.getBooksList(); for (Appliance book : list) { System.out.println("appliance: " + book.getName() + " from " + book.getDescription()); } } catch (Exception e) { e.printStackTrace(); } } //------------------- private static  T getPartial2(Class cls, String fname) { // get variables from our xml file, created before System.out.println(); System.out.println("Output from our XML File: "); Unmarshaller um; T alist = null; try { JAXBContext context = JAXBContext.newInstance(cls);; um = context.createUnmarshaller(); // um.setEventHandler(new DefaultValidationEventHandler()); FileReader fileReader = new FileReader(fname); alist = (T) um.unmarshal(fileReader ); //ArrayList list = alist.getBooksList(); // for (Appliance book : list) { // System.out.println("appliance: " + book.getName() + " from " // + book.getDescription()); // } } catch (Exception e) { e.printStackTrace(); } return alist; } //------------------- private static  T jaxbXmlFile2Class(Class cls, String fileName) { FileReader fr = null; char [] cbuf = null; try { fr = new FileReader(fileName); cbuf = new char[3000]; Arrays.fill(cbuf, ' '); fr.read(cbuf); }catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally{ try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } String s = new String(cbuf); return jaxbXmlString2Class(cls, s); } @SuppressWarnings("unchecked") private static  T jaxbXmlString2Class(Class cls, String xmlStr) { // get variables from our xml file, created before System.out.println(); System.out.println("Output from our XML File: "); Unmarshaller um; T alist = null; try { JAXBContext context = JAXBContext.newInstance(cls);; um = context.createUnmarshaller(); System.out.println(xmlStr); InputStream is = new ByteArrayInputStream(xmlStr.getBytes()); alist = (T) um.unmarshal( is ); } catch (Exception e) { e.printStackTrace(); } return alist; } }