繁体   English   中英

JAXB读取XML文档

[英]JAXB Reading XML document

我正在尝试读取XML文档并将其解码为Java Bean。 我的阅读部分已经解决,但遇到一个问题。 我基本上是在尝试解码XML文档的所有子节点,其根是“目录”。 如何使用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>

并将其解析为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() {

    }

......我收到错误: 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>

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

道:

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

正如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. Catalog不需要@XmlAccessorType -Annotation,因为只有一个字段由@XmlElement注释。
  2. 在将FIELD选择为访问类型时,将考虑所有字段,无论其可见性如何,除非使用@XmlTransient注释。
  3. 书籍ID是文档中的一个属性,因此必须使用@XmlAttribute进行声明。
  4. 必须使用Catalog.books上的@XmlElement来反映这本书元素的名称。 JAXB默认为这将是一书代替,因此不匹配的元素的字段(或属性)名称。

如前所述,演示代码是最低要求,应进行更改以满足您的需要(即字段可见性,适当的构造函数,getter,equals,hashCode,toString等)。

暂无
暂无

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

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