java |如何使用 JAXB 解析此 ('3-level' ) xml?

标签 java jaxb

我想学习 JAXB,但我的示例 xml 文件有问题。 xml:

<?xml version="1.0"?>
<catalog>
<books>
    <book id="bk101">
        <author>Gambardella, Matthew</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
        <description>An in-depth look at creating applications
            with XML.</description>
    </book>
<book id="bk102">
    <author>Ralls, Kim</author>
    <title>Midnight Rain</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-12-16</publish_date>
    <description>A former architect battles corporate zombies,
        an evil sorceress, and her own childhood to become queen
        of the world.</description>
</book>
<book id="bk103">
    <author>Corets, Eva</author>
    <title>Maeve Ascendant</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-11-17</publish_date>
    <description>After the collapse of a nanotechnology
        society in England, the young survivors lay the
        foundation for a new society.</description>
</book>
<book id="bk104">
    <author>Corets, Eva</author>
    <title>Oberon's Legacy</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2001-03-10</publish_date>
    <description>In post-apocalypse England, the mysterious
        agent known only as Oberon helps to create a new life
        for the inhabitants of London. Sequel to Maeve
        Ascendant.</description>
</book>
<book id="bk105">
    <author>Corets, Eva</author>
    <title>The Sundered Grail</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2001-09-10</publish_date>
    <description>The two daughters of Maeve, half-sisters,
        battle one another for control of England. Sequel to
        Oberon's Legacy.</description>
</book>
<book id="bk106">
    <author>Randall, Cynthia</author>
    <title>Lover Birds</title>
    <genre>Romance</genre>
    <price>4.95</price>
    <publish_date>2000-09-02</publish_date>
    <description>When Carla meets Paul at an ornithology
        conference, tempers fly as feathers get ruffled.</description>
</book>
<book id="bk107">
    <author>Thurman, Paula</author>
    <title>Splish Splash</title>
    <genre>Romance</genre>
    <price>4.95</price>
    <publish_date>2000-11-02</publish_date>
    <description>A deep sea diver finds true love twenty
        thousand leagues beneath the sea.</description>
</book>
<book id="bk108">
    <author>Knorr, Stefan</author>
    <title>Creepy Crawlies</title>
    <genre>Horror</genre>
    <price>4.95</price>
    <publish_date>2000-12-06</publish_date>
    <description>An anthology of horror stories about roaches,
        centipedes, scorpions  and other insects.</description>
</book>
<book id="bk109">
    <author>Kress, Peter</author>
    <title>Paradox Lost</title>
    <genre>Science Fiction</genre>
    <price>6.95</price>
    <publish_date>2000-11-02</publish_date>
    <description>After an inadvertant trip through a Heisenberg
        Uncertainty Device, James Salway discovers the problems
        of being quantum.</description>
</book>
<book id="bk110">
    <author>O'Brien, Tim</author>
    <title>Microsoft .NET: The Programming Bible</title>
    <genre>Computer</genre>
    <price>36.95</price>
    <publish_date>2000-12-09</publish_date>
    <description>Microsoft's .NET initiative is explored in
        detail in this deep programmer's reference.</description>
</book>
<book id="bk111">
    <author>O'Brien, Tim</author>
    <title>MSXML3: A Comprehensive Guide</title>
    <genre>Computer</genre>
    <price>36.95</price>
    <publish_date>2000-12-01</publish_date>
    <description>The Microsoft MSXML3 parser is covered in
        detail, with attention to XML DOM interfaces, XSLT processing,
        SAX and more.</description>
</book>
<book id="bk112">
    <author>Galos, Mike</author>
    <title>Visual Studio 7: A Comprehensive Guide</title>
    <genre>Computer</genre>
    <price>49.95</price>
    <publish_date>2001-04-16</publish_date>
    <description>Microsoft Visual Studio 7 is explored in depth,
        looking at how Visual Basic, Visual C++, C#, and ASP+ are
        integrated into a comprehensive development
        environment.</description>
</book>
</books>
<movies>
    <movie id="m101">
        <author>George Lucas</author>
        <title>Star Wars</title>
        <genre>Science Fiction</genre>
        <price>32.95</price>
    </movie>
    <movie id="m202">
        <author>Francis Ford Coppola</author>
        <title>The Godfather</title>
        <genre>Drama</genre>
        <price>36.95</price>
    </movie>
</movies>
</catalog

这是我的代码,它不起作用。 主要:

public class Main {

public static void main(String[] args) throws Exception {

    Scanner scanner = new Scanner(System.in);

    System.out.println("Path: ");
    String filePath = scanner.next();

    JAXBContext jaxbContext = JAXBContext.newInstance(Catalog.class);
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    Catalog catalog = (Catalog) unmarshaller.unmarshal(new File(filePath));

    // test
    System.out.println("All titles in uploaded catalog: ");

    for (int b = 0; b<catalog.getBooks().getBookList().size(); b++) {
        catalog.getBooks().getBookList().get(b).getTitle();
        catalog.getBooks().getBookList().get(b).getPrice();
    }

    for (int m = 0; m<catalog.getMovies().getMovieList().size(); m++) {
        catalog.getMovies().getMovieList().get(m).getTitle();
        catalog.getMovies().getMovieList().get(m).getPrice();
    }

}
}

书:

为简洁起见,省略 电影:

为简洁起见,省略 书籍:

@XmlRootElement(name = "books")
public class Books {

private List<Book> bookList = new ArrayList<>();

@XmlElements(@XmlElement(name = "books"))
public List<Book> getBookList() {
    return bookList;
}

public void setBookList(List<Book> bookList) {
    this.bookList = bookList;
}
}

电影:

@XmlRootElement(name = "movies")
public class Movies {

private List<Movie> movieList = new ArrayList<>();

@XmlElements(@XmlElement(name = "movies"))
public List<Movie> getMovieList() {
    return movieList;
}

public void setMovieList(List<Movie> movieList) {
    this.movieList = movieList;
}
}

目录:

@XmlRootElement(name = "catalog")
public class Catalog {
private Books books = new Books();

private Movies movies = new Movies();

//@XmlElements(@XmlElement(name = "books"))
public Books getBooks() {
    return books;
}

public void setBooks(Books books) {
    this.books = books;
}

//@XmlElements(@XmlElement(name = "movies"))
public Movies getMovies() {
    return movies;
}

public void setMovies(Movies movies) {
    this.movies = movies;
}
}

我认为 Catalog 类中可能存在一些错误,但我不知道如何修改它,而且我尝试将其转换为 xsd 并使用 xcj 生成类,但实际上 xcj 无法在我的操作系统上运行。感谢您的关注。

最佳答案

您实际上可以删除中间的 BooksMovies 类,您不需要它们。这是使用 @XmlElementWrapper 的版本:

public class Catalog {

    @XmlElementWrapper(name="books")
    @XmlElement(name="book")
    public List<Book> books;

}

public class Book {

    @XmlAttribute
    public String id;
    public String author;
    public String title;
    public String genre;
    public BigDecimal price;
    @XmlElement(name="publish_date")
    public XMLGregorianCalendar publishDate;
    public String description;
}

测试:

@Test
public void unmarshallsCatalog() throws JAXBException, IOException {

    JAXBContext context = JAXBContext.newInstance(Catalog.class);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    try (InputStream is = Thread.currentThread()
                              .getContextClassLoader()
                              .getResourceAsStream("catalog.xml")) {

        Catalog catalog = unmarshaller.unmarshal(new StreamSource(is), Catalog.class).getValue();
        Assert.assertEquals(catalog.books.size(), 12);

    }
}

以下内容也对我有用:

public class Catalog {
    public Books books; 
}

public class Books {
    @XmlElement(name = "book")
    public List<Book> bookList;
}

我认为您的错误可能是在 Books 类中:

@XmlElements(@XmlElement(name = "books"))
public List<Book> getBookList() {
    return bookList;
}

您必须映射 book 元素,而不是 books 元素。

此外,像 @XmlElements(@XmlElement(name = "books")) 这样的注释也不会执行您可能认为的操作。它不映射书籍列表。对于一个元素来说,它甚至没有意义。

@XmlElements 可用于将不同元素映射到一个属性。假设您有一个类似以下的 XML:

马修·甘巴德拉 XML 开发人员指南 电脑 44.95 2000年10月1日 深入了解创建应用程序 使用 XML。 乔治·卢卡斯 星球大战 科幻小说 32.95

基本上,书籍电影混合在一个目录中。 BookMovie 可以实现相同的接口(interface) Item。在这种情况下,您可能希望将元素 bookmovie 映射到同一属性 items。您可以这样做:

@XmlElements({
    @XmlElement(name="book", type=Book.class),
    @XmlElement(name="movie", type=Movie.class)
})
public List<? extends Item> items;

根据元素名称,JAXB 将解码 BookMovie 并将它们添加到 items 列表中。

关于 java |如何使用 JAXB 解析此 ('3-level' ) xml?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49767013/

相关文章:

java - Tomcat 和 JDBC

java - JNI - 如何将 jshortArray 转换为短 *

java - SOAPMessage.getMessageBody() 打印 null

java - Jaxb。自定义字段命名行为(camelCase 到 underscore_case)

spring - JAXBException : "package" doesnt contain ObjectFactory. 类或 jaxb.in​​dex

java - Android游戏菜单可点击

每个连接模型的 Java 线程与 NIO

java - 如何知道java进程等待了多少时间

java - 从 wsdl 生成 java 类

java - Jaxb 复杂的 xml 解码