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

如何用JAXB将属性编组为嵌套根元素式列表?附医院列表实现

针对你用JAXB保存带独立服务列表的医院需求,结合你已经实现的Wrapper和Hopital类,我来给你完善整个方案,确保功能完整且符合JAXB的最佳实践:

1. 完善核心实体类

首先,你的Hopital类需要添加服务列表字段,并配合JAXB注解让XML结构更清晰;同时我们需要补充Service类来表示医院的具体服务。

Wrapper类(保持你的实现,它是列表的根容器)

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;

public class Wrapper<T> {
    private List<T> items = new ArrayList<T>();
    
    @XmlAnyElement(lax=true)
    public List<T> getItems() {
        return items;
    }
}

注解说明:@XmlAnyElement(lax=true)允许JAXB识别并序列化已经添加JAXB注解的实体类(比如Hopital),让Wrapper能灵活包装任意类型的列表。

Hopital类(补充服务列表)

import java.util.List;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="hopital")
public class Hopital {
    private int id;
    private String nom, adresse, categorie;
    
    // 为医院添加服务列表,用注解生成清晰的XML结构
    @XmlElementWrapper(name="services") // 外层包裹标签
    @XmlElement(name="service") // 单个服务的标签
    private List<Service> services;
    
    // 必须提供无参构造器(JAXB要求)
    public Hopital() {}
    
    // 带参构造器方便实例化
    public Hopital(int id, String nom, String adresse, String categorie, List<Service> services) {
        this.id = id;
        this.nom = nom;
        this.adresse = adresse;
        this.categorie = categorie;
        this.services = services;
    }
    
    // 补充getter和setter方法(JAXB需要访问字段)
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getNom() { return nom; }
    public void setNom(String nom) { this.nom = nom; }
    public String getAdresse() { return adresse; }
    public void setAdresse(String adresse) { this.adresse = adresse; }
    public String getCategorie() { return categorie; }
    public void setCategorie(String categorie) { this.categorie = categorie; }
    public List<Service> getServices() { return services; }
    public void setServices(List<Service> services) { this.services = services; }
}

Service类(表示医院的具体服务)

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;

@XmlAccessorType(XmlAccessType.FIELD)
public class Service {
    private int serviceId;
    private String nomService;
    private String description;
    
    // JAXB要求的无参构造器
    public Service() {}
    
    public Service(int serviceId, String nomService, String description) {
        this.serviceId = serviceId;
        this.nomService = nomService;
        this.description = description;
    }
    
    // 补充getter和setter
    public int getServiceId() { return serviceId; }
    public void setServiceId(int serviceId) { this.serviceId = serviceId; }
    public String getNomService() { return nomService; }
    public void setNomService(String nomService) { this.nomService = nomService; }
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
}

2. JAXB序列化/反序列化工具类

编写一个工具类来封装保存和读取医院列表的逻辑,方便复用:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.util.List;

public class JaxbHopitalUtil {
    // 保存医院列表到XML文件
    public static void saveHopitals(List<Hopital> hopitalList, String filePath) throws JAXBException {
        Wrapper<Hopital> wrapper = new Wrapper<>();
        wrapper.getItems().addAll(hopitalList);
        
        // 初始化JAXB上下文,要包含所有需要序列化的类
        JAXBContext context = JAXBContext.newInstance(Wrapper.class, Hopital.class, Service.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 格式化XML
        
        // 序列化到文件和控制台(方便调试)
        marshaller.marshal(wrapper, new File(filePath));
        marshaller.marshal(wrapper, System.out);
    }
    
    // 从XML文件读取医院列表
    public static List<Hopital> loadHopitals(String filePath) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(Wrapper.class, Hopital.class, Service.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        Wrapper<Hopital> wrapper = (Wrapper<Hopital>) unmarshaller.unmarshal(new File(filePath));
        return wrapper.getItems();
    }
}

3. 测试示例

编写主类测试整个流程:

import java.util.Arrays;
import javax.xml.bind.JAXBException;

public class Main {
    public static void main(String[] args) {
        // 构建服务实例
        Service emergency = new Service(1, "急诊", "24小时全天候接诊");
        Service internal = new Service(2, "内科", "常见内科疾病诊疗");
        Service general = new Service(3, "全科", "基础医疗与健康咨询");
        
        // 构建医院实例
        Hopital centralHopital = new Hopital(1, "市中心医院", "XX大道123号", "三级甲等", Arrays.asList(emergency, internal));
        Hopital communityHopital = new Hopital(2, "阳光社区医院", "YY路456号", "一级", Arrays.asList(general));
        
        // 保存到XML
        try {
            JaxbHopitalUtil.saveHopitals(Arrays.asList(centralHopital, communityHopital), "hopitals.xml");
            System.out.println("\n医院列表已成功保存到XML文件!");
            
            // 可选:读取XML验证
            List<Hopital> loadedHopitals = JaxbHopitalUtil.loadHopitals("hopitals.xml");
            System.out.println("\n读取到的医院数量:" + loadedHopitals.size());
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

4. 生成的XML结构示例

运行后会生成如下格式的XML,每个医院都包含独立的服务列表:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wrapper>
    <hopital>
        <id>1</id>
        <nom>市中心医院</nom>
        <adresse>XX大道123号</adresse>
        <categorie>三级甲等</categorie>
        <services>
            <service>
                <serviceId>1</serviceId>
                <nomService>急诊</nomService>
                <description>24小时全天候接诊</description>
            </service>
            <service>
                <serviceId>2</serviceId>
                <nomService>内科</nomService>
                <description>常见内科疾病诊疗</description>
            </service>
        </services>
    </hopital>
    <hopital>
        <id>2</id>
        <nom>阳光社区医院</nom>
        <adresse>YY路456号</adresse>
        <categorie>一级</categorie>
        <services>
            <service>
                <serviceId>3</serviceId>
                <nomService>全科</nomService>
                <description>基础医疗与健康咨询</description>
            </service>
        </services>
    </hopital>
</wrapper>

内容的提问来源于stack exchange,提问作者Boussadjra Brahim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:21:58