如何在JAXB中为不同值的多组对象编组?

时间:2014-07-25 14:31:41

标签: java xml object jaxb marshalling

我试图标记标签不断变化的标签。我继续覆盖对象值,并在I Marshal时以标签的相同值结束。

期望的输出:

<bookshelf>
  <shelfnumber> 001 </shelfnumber>
  <shelfowner> John Snow </shelfowner>
     <book>
        <Author>Ned Stark</Author>
        <Chapters>24</Chapters>
               <Chapter1>.......</Chapter1>
               <Chapter2>.......</Chapter2>
     </book>
     <book>

        <Author>Rob Stark</Author>
        <Chapters>24</Chapters>
               <Chapter1>.......</Chapter1>
               <Chapter2>.......</Chapter2>
     </book>
     <magazine>
        <Author>Tyrion Lannister</Author>
        <Pages>24</Pages>
               <Page1>.......</Page1>
               <Page2>.......</Page2>
     </magazine>    
</bookshelf>

我有一个switch语句在迭代包含数据库中提取的值的arraylist时创建对象。我最终覆盖了最后一个对象,所以我正在寻找一种方法来保存一组在迭代器的每次传递中填充的对象。

public class TagFactory {
/*
 * Creates an arraylist from which to read the values and populate the tags
 */
private ArrayList<Data> Values;

public TagFactory(ArrayList<Data> values) {
    Values = values;

}

/*
 * Populates the Tran tags for the output based on the values in the Vales
 * arraylist. Uses the index of each cell to match up with the corresponding
 * tags
 */
public Tran TagPopulator() {

    BookShelf bookshelf = new BookShelf();
    Magazine mag = new Magazine();
    Book book = new book();
    Page page = new Page();
    Chapter chapter = new Chapter();


    /*
     * Create iterator and iterate though the extracted data arraylist
     */

    /*
     * Static Fields constructors
     */
    bookshelf.setNumber(BigInteger.valueOf(6));
    bookshelf.setAuthor("John Snow");
    ...

    Iterator<Data> ValuesIt = Values.iterator();

    boolean Endofchapter = false;
    boolean Endofpage = false;

    while (ValuesIt.hasNext()) {

        /*
         * Data object to hold the values
         */
        Data data = ValuesIt.next();

        /*
         * Select the appropriate class object constructor based on the
         * index of the cell This index was previously matched up in
         * HeaderValues and is used for a reference Type modification was
         * done for each of the constructor's requirements.
         */


        switch (data.getcellIndex()) {

        // Book->Author
        case 0:
            book.setAuthor(data.getcellValue());

            break;

        // Book->Chapter-> Chap #
        case 1:
            Chapter.add(data.getcellValue());
            ...
            Endofchapter = true;

            break;

        // Mag -> Author
        case 2:
            mag.setAuthor(data.getcellValue());
            break;

        // Mag->Page->Page#
        case 3:
            /*
             * Page object created and modified
             */
            page.setnum(data.getcellValue());

            Endofpage = true;
            break;

        ...
    if(Endofpage){
        mag.add(page);
    }
    if(Endofchapter){
        book.add(chapter);
    }
    bookshelf.add(mag);
    bookshelf.add(book)
...

我在循环完成后进行编组。

添加了封送功能

 public class XMLWriter {

    private String FileOutput;
    private Tran Transaction;
    ...

    public void FileOut () {
        try {
            /*
             * Marshal the classes into and XML output
             */
             File file = new File(FileOutput);
             JAXBContext JC = JAXBContext.newInstance(Tran.class);
             Marshaller JCMarshaller = JC.createMarshaller();

             JCMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

             JCMarshaller.marshal(Transaction, file);
             JCMarshaller.marshal(Transaction, System.out);

         } catch (JAXBException e) {
             e.printStackTrace();
         } 
    }
}

添加了对类的调用以编写XML。

XMLWriter output = new XMLWriter(outputFilename, newBookshelf.TagPopulator());
    output.FileOut();

除了XMLWriter和TagFactory之外的所有对象都是由JAXB从模式生成的。

1 个答案:

答案 0 :(得分:0)

由于我们没有显示XML架构,因此下面的代码可能不完全合适。但是,它确实根据XML示例生成有效的XML。列表由扫描程序替换,从文本文件中读取。你的while / switch的意图对我来说并不是很清楚。我无法想象最后这些add()调用如何正常工作。

请注意,在将DOM元素插入其父元素之前,不必完成表示DOM树中元素的对象。如需重复添加,请参考最新/当前的书籍或杂志。

可能有另一种方法来确定章节和页面的数量。我完全不知道章节或页面内应该发生什么。

    BookShelf bookshelf = new BookShelf();
    bookshelf.setShelfnumber( "001" );
    bookshelf.setShelfowner( "John Doe" );

    File f = new File( "data.txt" );
    Scanner scanner = new Scanner( f );
    Book book = null;
    Magazine magazine = null;
    int chapters = 0;
    int pages = 0;
    while( scanner.hasNext() ){
        int cellid = scanner.nextInt();
        switch(cellid){
        case 0:
            book = new Book();
            bookshelf.getBookOrMagazine().add( book );
            book.setAuthor( scanner.nextLine() );
            chapters = 0;
            break;
        case 1:
            Chapter chapter = new Chapter();
            book.getChapter().add( chapter );
            chapter.setNumber( scanner.nextInt() );
            book.setChapters( ++chapters );
            break;
        case 2:
            magazine = new Magazine();
            bookshelf.getBookOrMagazine().add( magazine );
            magazine.setAuthor( scanner.nextLine() );
            pages = 0;
            break;
        case 3:
            Page page = new Page();
            magazine.getPage().add( page );
            page.setNumber( scanner.nextInt() );
            magazine.setPages( ++pages );
            break;
        }
    }

我使用的XML架构文件:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        version="2.0">
<xs:element name="bookshelf" type="BookShelf"/>
<xs:complexType name="BookShelf">
  <xs:sequence>
    <xs:element name="shelfnumber" type="xs:string"/>
    <xs:element name="shelfowner"  type="xs:string"/>
    <xs:choice maxOccurs="unbounded">
      <xs:element name="book"     type="Book"/>
      <xs:element name="magazine" type="Magazine"/>
    </xs:choice>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="Book">
  <xs:sequence>
    <xs:element name="Author"   type="xs:string"/>
    <xs:element name="Chapters" type="xs:int"/>
    <xs:element name="chapter"  type="Chapter" maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="Magazine">
  <xs:sequence>
    <xs:element name="Author" type="xs:string"/>
    <xs:element name="Pages"  type="xs:int"/>
    <xs:element name="page"   type="Page" maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="Chapter">
  <xs:sequence>
    <xs:element name="number" type="xs:int"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="Page">
  <xs:sequence>
    <xs:element name="number" type="xs:int"/>
  </xs:sequence>
</xs:complexType>
</xs:schema>