简体   繁体   English

JAXB读取XML文档

[英]JAXB Reading XML document

I'm trying to read an XML document and decode it in to Java Beans. 我正在尝试读取XML文档并将其解码为Java Bean。 I have the reading part settled but I run in to an issue. 我的阅读部分已经解决,但遇到一个问题。 I'm basically trying to decode all the child nodes of the XML document, root being "catalog". 我基本上是在尝试解码XML文档的所有子节点,其根是“目录”。 How do I do this using the XMLDecoder? 如何使用XMLDecoder做到这一点?

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

I'm trying to read the following document 我正在尝试阅读以下文档

    <?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>

And Parse it in to a Book Object 并将其解析为Book对象

@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() {

    }

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

How do I only access the child nodes using JAXB? 如何仅使用JAXB访问子节点?

UPDATE 更新

Catalog Class: 目录类别:

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

Book class: 书本类:

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

As already pointed out by JB Nizet you definitely need an enclosing Catalog object. 正如JB Nizet所指出的,您肯定需要一个封闭的Catalog对象。 The following is the bare minimum to be able to unmarshal the provided XML document using JAXB and extract the book from it: 以下是能够使用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);
    }

}

Some things are worth mentioning here: 这里有些事情值得一提:

  1. The @XmlAccessorType -Annotation is not necessary with Catalog as there is only one field which is annotated with @XmlElement . Catalog不需要@XmlAccessorType -Annotation,因为只有一个字段由@XmlElement注释。
  2. When chosing FIELD as access type all fields are taken into account regardless of their visibility unless annotated with @XmlTransient . 在将FIELD选择为访问类型时,将考虑所有字段,无论其可见性如何,除非使用@XmlTransient注释。
  3. The book ID is an attribute in the document, so it must be declared as such using @XmlAttribute . 书籍ID是文档中的一个属性,因此必须使用@XmlAttribute进行声明。
  4. @XmlElement on Catalog.books was necessary to reflect the name of the book-Elements. 必须使用Catalog.books上的@XmlElement来反映这本书元素的名称。 JAXB defaults to the field (or property) name which would be book s instead and thus not match the elements. JAXB默认为这将是一书代替,因此不匹配的元素的字段(或属性)名称。

As said before the demonstration code is the bare minimum and should be changed to fit your needs (ie field visibility, proper constructor, getters, equals, hashCode, toString etc.) 如前所述,演示代码是最低要求,应进行更改以满足您的需要(即字段可见性,适当的构造函数,getter,equals,hashCode,toString等)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM