You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于现有Java类,如何从XML生成填充完整的Registry对象?

问题描述

给定如下XML文件,以及已定义的6个Java类(Catalog、Cd、Album、Artist、Country、Registry),其中Catalog和Cd类已通过Jackson注解完成XML映射,需要生成填充完整字段的Registry对象。

输入XML文件

<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
    <CD>
        <TITLE>Empire Burlesque</TITLE>
        <ARTIST>Bob Dylan</ARTIST>
        <COUNTRY>USA</COUNTRY>
        <COMPANY>Columbia</COMPANY>
        <PRICE>10.90</PRICE>
        <YEAR>1985</YEAR>
    </CD>
    <CD>
        <TITLE>Hide your heart</TITLE>
        <ARTIST>Bonnie Tyler</ARTIST>
        <COUNTRY>UK</COUNTRY>
        <COMPANY>CBS Records</COMPANY>
        <PRICE>9.90</PRICE>
        <YEAR>1988</YEAR>
    </CD>
    <CD>
        <TITLE>Greatest Hits</TITLE>
        <ARTIST>Dolly Parton</ARTIST>
        <COUNTRY>USA</COUNTRY>
        <COMPANY>RCA</COMPANY>
        <PRICE>9.90</PRICE>
        <YEAR>1982</YEAR>
    </CD>
    <CD>
        <TITLE>Still got the blues</TITLE>
        <ARTIST>Gary Moore</ARTIST>
        <COUNTRY>UK</COUNTRY>
        <COMPANY>Virgin records</COMPANY>
        <PRICE>10.20</PRICE>
        <YEAR>1990</YEAR>
    </CD>
    <CD>
        <TITLE>Eros</TITLE>
        <ARTIST>Eros Ramazzotti</ARTIST>
        <COUNTRY>EU</COUNTRY>
        <COMPANY>BMG</COMPANY>
        <PRICE>9.90</PRICE>
        <YEAR>1997</YEAR>
    </CD>
    <CD>
        <TITLE>One night only</TITLE>
        <ARTIST>Bee Gees</ARTIST>
        <COUNTRY>UK</COUNTRY>
        <COMPANY>Polydor</COMPANY>
        <PRICE>10.90</PRICE>
        <YEAR>1998</YEAR>
    </CD>
</CATALOG>

已定义的Java类

目标结构类(需填充为Registry)

public class Registry {
    private List<Country> countries = new ArrayList<>();
}

public class Country {
    private String name; // 对应XML中的<COUNTRY>节点内容
    private List<Artist> artists = new ArrayList<>();
}

public class Artist {
    private String name; // 对应XML中的<ARTIST>节点内容
    private List<Album> albums = new ArrayList<>();
}

public class Album {
    private String name; // 对应XML中的<TITLE>节点内容
    private int year; // 对应XML中的<YEAR>节点内容
}

Jackson XML映射类

public class Catalog {
    @JacksonXmlProperty(localName = "CD")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List cds;

    public List getCds() {
        return cds;
    }
}

public class Cd {
    @JsonProperty("TITLE") // 专辑名称
    private String title;
    @JsonProperty("ARTIST") // 艺术家名称
    private String artist;
    @JsonProperty("COUNTRY") // 国家名称
    private String country;
    @JsonProperty("COMPANY")
    private String company;
    @JsonProperty("PRICE")
    private double price;
    @JsonProperty("YEAR")  // 发行年份
    private int year;
}
解决方案

1. 引入Jackson XML依赖

确保项目中添加Jackson XML处理的依赖,以Maven为例:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.15.2</version> <!-- 使用最新稳定版本 -->
</dependency>

2. 优化Jackson映射类

原Catalog类的cds字段为原始类型,建议改为泛型List<Cd>避免类型转换警告,并添加setter方法:

public class Catalog {
    @JacksonXmlProperty(localName = "CD")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Cd> cds;

    public List<Cd> getCds() {
        return cds;
    }

    public void setCds(List<Cd> cds) {
        this.cds = cds;
    }
}

为Cd类添加所有字段的getter/setter,确保Jackson能正确反序列化:

public class Cd {
    @JsonProperty("TITLE")
    private String title;
    @JsonProperty("ARTIST")
    private String artist;
    @JsonProperty("COUNTRY")
    private String country;
    @JsonProperty("COMPANY")
    private String company;
    @JsonProperty("PRICE")
    private double price;
    @JsonProperty("YEAR")
    private int year;

    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
    public String getArtist() { return artist; }
    public void setArtist(String artist) { this.artist = artist; }
    public String getCountry() { return country; }
    public void setCountry(String country) { this.country = country; }
    public String getCompany() { return company; }
    public void setCompany(String company) { this.company = company; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }
    public int getYear() { return year; }
    public void setYear(int year) { this.year = year; }
}

3. 补充目标类的Getter/Setter

为Registry、Country、Artist、Album添加getter/setter,确保能正常访问和修改字段:

import java.util.ArrayList;
import java.util.List;

public class Registry {
    private List<Country> countries = new ArrayList<>();

    public List<Country> getCountries() {
        return countries;
    }

    public void setCountries(List<Country> countries) {
        this.countries = countries;
    }
}

public class Country {
    private String name;
    private List<Artist> artists = new ArrayList<>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Artist> getArtists() {
        return artists;
    }

    public void setArtists(List<Artist> artists) {
        this.artists = artists;
    }
}

public class Artist {
    private String name;
    private List<Album> albums = new ArrayList<>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Album> getAlbums() {
        return albums;
    }

    public void setAlbums(List<Album> albums) {
        this.albums = albums;
    }
}

public class Album {
    private String name;
    private int year;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }
}

4. 实现转换逻辑

通过Jackson将XML反序列化为Catalog,再遍历Cd列表,按国家→艺术家→专辑的层级分组,构建完整的Registry对象:

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class RegistryGenerator {
    public static void main(String[] args) throws IOException {
        // 1. 读取XML并反序列化为Catalog
        XmlMapper xmlMapper = new XmlMapper();
        Catalog catalog = xmlMapper.readValue(new File("catalog.xml"), Catalog.class);

        // 2. 构建Registry层级结构
        Registry registry = new Registry();
        Map<String, Country> countryCache = new HashMap<>();

        for (Cd cd : catalog.getCds()) {
            // 缓存国家,避免重复创建
            Country country = countryCache.get(cd.getCountry());
            if (country == null) {
                country = new Country();
                country.setName(cd.getCountry());
                countryCache.put(cd.getCountry(), country);
                registry.getCountries().add(country);
            }

            // 缓存艺术家,避免重复创建
            Map<String, Artist> artistCache = new HashMap<>();
            country.getArtists().forEach(artist -> artistCache.put(artist.getName(), artist));
            Artist artist = artistCache.get(cd.getArtist());
            if (artist == null) {
                artist = new Artist();
                artist.setName(cd.getArtist());
                country.getArtists().add(artist);
            }

            // 创建并添加专辑
            Album album = new Album();
            album.setName(cd.getTitle());
            album.setYear(cd.getYear());
            artist.getAlbums().add(album);
        }

        // 验证结果:打印Registry内容
        printRegistry(registry);
    }

    // 辅助打印方法
    private static void printRegistry(Registry registry) {
        for (Country country : registry.getCountries()) {
            System.out.println("国家: " + country.getName());
            for (Artist artist : country.getArtists()) {
                System.out.println("  艺术家: " + artist.getName());
                for (Album album : artist.getAlbums()) {
                    System.out.println("    专辑: " + album.getName() + " (" + album.getYear() + ")");
                }
            }
        }
    }
}

运行说明

  1. 将XML文件保存为catalog.xml放在项目根目录,或修改代码中的文件路径。
  2. 运行RegistryGenerator类,即可生成填充完整的Registry对象,控制台会打印验证内容。

内容的提问来源于stack exchange,提问作者Nikita Zakharov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:05:17