JAXB阅读XML文档

时间:2017-02-19 20:24:20

标签: java xml jaxb

我正在尝试读取XML文档并将其解码为Java Bean。我的阅读部分已经解决,但我遇到了一个问题。我基本上试图解码XML文档的所有子节点,root是“目录”。如何使用XMLDecoder执行此操作?

的XMLDecoder:

private static Book jaxbXMLToObject() {
    try {
        JAXBContext context = JAXBContext.newInstance(Book.class);
        Unmarshaller un = context.createUnmarshaller();
        Book book = (Book) un.unmarshal(new File("PATH"));
        return book;
    } catch (JAXBException e) {
        e.printStackTrace();
    }
    return null;
}

我正在尝试阅读以下文档

    <?xml version="1.0"?>
    <catalog>
       <book id="1">
          <author>Isaac Asimov</author>
          <title>Foundation</title>
          <genre>Science Ficition</genre>
          <price>164</price>
          <publish_date>1951-08-21</publish_date>
          <description>Foundation is the first novel in Isaac Asimovs Foundation Trilogy (later expanded into The Foundation Series). Foundation is a cycle of five interrelated short stories, first published as a single book by Gnome Press in 1951. Collectively they tell the story of the Foundation, an institute to preserve the best of galactic civilization after the collapse of the Galactic Empire.</description>
       </book>
   </catalog>

将其解析为书籍对象

@XmlRootElement(name = "book")
@XmlType(propOrder = {"id", "price", "title", "author", "genre", "description"})
public class Book {
    private int id;
    private int price;
    private String title;
    private String author;
    private String genre;
    private String description;
    private Date publish_date;

    public Book() {

    }

...... 我收到错误:jjavax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"catalog"). Expected elements are <{}book>

如何仅使用JAXB访问子节点?

更新

目录类:

@XmlRootElement(name = "catalog")

    public class Catalog {
        @XmlElement(name = "book")
        List<Book> books;

        public List<Book> getBooks() {
            return books;
        }

        public void setBooks(List<Book> books) {
            this.books = books;
        }
    }

图书课程:

@XmlAccessorType(XmlAccessType.FIELD)
public class Book {
    @XmlAttribute
    int id;
    private int price;
    private String title;
    private String author;
    private String genre;
    private String description;
    private Date publish_date;

    public Book() {

    }

    public Book(int id, int price, String title, String genre, String description, Date publicationDate) {
        this.id = id;
        this.price = price;
        this.title = title;
        this.genre = genre;
        this.description = description;
        this.publish_date = publicationDate;
    }

    public int getId() {
        return id;
    }

    public int getPrice() {
        return price;
    }

    public String getTitle() {
        return title;
    }

    public String getGenre() {
        return genre;
    }

    public String getDescription() {
        return description;
    }

    public Date getPublicationDate() {
        return publish_date;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setGenre(String genre) {
        this.genre = genre;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void setPublish_date(String publish_date) {
        this.publish_date = new Date();
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Date getPublish_date() {
        return publish_date;
    }

    public String toJSON() {
        ObjectMapper mapper = new ObjectMapper();

        try {
            return mapper.writeValueAsString(this);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", price=" + price +
                ", title='" + title + '\'' +
                ", genre='" + genre + '\'' +
                ", description='" + description + '\'' +
                ", publicationDate=" + publish_date +
                '}';
    }
}

DAO:

public class BooksDAO {

    public BooksDAO() {
    }

    public List<Book> getBooks() {
        Catalog catalog = jaxbXMLToObject();
        return catalog.getBooks();
    }

    private static Catalog jaxbXMLToObject() {
        try {
            return JAXB.unmarshal(new File("PATH"), Catalog.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

1 个答案:

答案 0 :(得分:1)

正如JB Nizet已经指出的那样,你肯定需要一个封闭的Catalog对象。以下是能够使用JAXB解组提供的XML文档并从中提取书籍的最低要求:

public class ReadXMLUsingJAXB {

    static class Catalog {
        @XmlElement(name = "book")
        List<Book> books;
    }

    @XmlAccessorType(XmlAccessType.FIELD)
    static class Book {
        @XmlAttribute
        int id;
        String author;
        String title;
        String genre;
        int price;
        Date publish_date;
        String description;
    }

    private static Book firstBookFromXML() {
        Catalog catalog = JAXB.unmarshal(new File("PATH"), Catalog.class);
        return catalog.books.get(0);
    }

    public static void main(String[] args) {
        Book book = firstBookFromXML();
        System.out.println(book.id + ", " + book.author + ", " + book.title 
                + ", " + book.genre + ", " + book.price 
                + ", " + book.publish_date + ", " + book.description);
    }

}

有些事情值得一提:

  1. 目录中不需要@XmlAccessorType - 注释,因为只有一个字段用@XmlElement注释。
  2. 选择FIELD作为访问类型时,除非使用@XmlTransient进行注释,否则所有字段都会被考虑在内,无论其可见性如何。
  3. 图书ID是文档中的属性,因此必须使用@XmlAttribute声明它。
  4. Catalog.books上的
  5. @XmlElement是必要的,以反映书籍元素的名称。 JAXB默认为字段(或属性)名称,而不是书籍 s ,因此与元素不匹配。
  6. 如前所述,演示代码是最低限度,应该根据您的需要进行更改(即字段可见性,正确的构造函数,getter,equals,hashCode,toString等)。