如何使用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; } }