如何用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
相关产品推荐
相关产品推荐

