如何将XML重复标签fechaEnvio映射至Java 8对象?
问题描述
需要将以下XML中的重复<fechaEnvio>标签映射到Java对象的List<String>属性中,使用Java 8的DOM解析完成。
待解析的XML
<mensajeWS> <respuestaGetCabecerasType> <cabeceras> <cabecera> <id>1234</id> <tipoMensaje>3</tipoMensaje> <datos> <fechaEnvio>2023-12-13T00:05:00</fechaEnvio> <fechaEnvio>2023-12-14T00:05:00</fechaEnvio> </datos> </cabecera> </cabeceras> </respuestaGetCabecerasType> </mensajeWS>
对应的Java对象
Cabecera类
public class Cabecera implements Serializable { private static final long serialVersionUID = -865317642824095952L; private int id; private int tipoMensaje; private DatosRecepcion datos; // 补充getter、setter方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public int getTipoMensaje() { return tipoMensaje; } public void setTipoMensaje(int tipoMensaje) { this.tipoMensaje = tipoMensaje; } public DatosRecepcion getDatos() { return datos; } public void setDatos(DatosRecepcion datos) { this.datos = datos; } }
DatosRecepcion类
public class DatosRecepcion implements Serializable { private static final long serialVersionUID = -6703565058845907875L; private List<String> fechaEnvio; // 补充getter、setter方法 public List<String> getFechaEnvio() { return fechaEnvio; } public void setFechaEnvio(List<String> fechaEnvio) { this.fechaEnvio = fechaEnvio; } }
现有DOM解析代码片段
List<Cabecera> listaCabeceras = new ArrayList<>(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new InputSource(new StringReader(xml.toString()))); System.out.println("Root element: " + document.getDocumentElement().getNodeName()); NodeList nList = document.getElementsByTagName("cabecera"); for(int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); System.out.println("Current Element: " + nNode.getNodeName()); Element element = (Element) nNode; System.out.println("id: " + element.getElementsByTagName("id").item(0).getTextContent()); System.out.println("Tipo de mensaje: " + element.getElementsByTagName("tipoMensaje").item(0).getTextContent()); System.out.println("Fecha de Envio: " + element.getElementsByTagName("fechaEnvio").item(0).getTextContent()); Cabecera cabecera = new Cabecera(); cabecera.setId(Integer.parseInt(element.getElementsByTagName("id").item(0).getTextContent())); cabecera.setTipoMensaje(Integer.parseInt(element.getElementsByTagName("tipoMensaje").item(0).getTextContent())); //cabecera.getDatos().setFechaEnvio(element.getElementsByTagName("fechaEnvio").item(0).getTextContent()); listaCabeceras.add(cabecera); }
解决方案
要处理重复的<fechaEnvio>标签,需遍历所有该标签节点,将文本内容收集到List后赋值给DatosRecepcion对象,具体步骤如下:
- 定位并获取所有
<fechaEnvio>节点:在处理每个<cabecera>元素时,获取其下所有<fechaEnvio>节点的列表。 - 收集日期字符串:初始化一个
ArrayList<String>,遍历每个<fechaEnvio>节点,将文本内容添加到列表中。 - 赋值并关联对象:创建
DatosRecepcion实例,将日期列表赋值给它,再将该实例设置到Cabecera对象中。
修改后的完整解析代码:
List<Cabecera> listaCabeceras = new ArrayList<>(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new InputSource(new StringReader(xml.toString()))); System.out.println("Root element: " + document.getDocumentElement().getNodeName()); NodeList nList = document.getElementsByTagName("cabecera"); for(int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); System.out.println("Current Element: " + nNode.getNodeName()); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) nNode; // 解析id和tipoMensaje Cabecera cabecera = new Cabecera(); cabecera.setId(Integer.parseInt(element.getElementsByTagName("id").item(0).getTextContent())); cabecera.setTipoMensaje(Integer.parseInt(element.getElementsByTagName("tipoMensaje").item(0).getTextContent())); // 解析datos下的fechaEnvio列表 DatosRecepcion datos = new DatosRecepcion(); List<String> fechaEnvioList = new ArrayList<>(); // 获取所有fechaEnvio节点 NodeList fechaEnvioNodes = element.getElementsByTagName("fechaEnvio"); for (int j = 0; j < fechaEnvioNodes.getLength(); j++) { Node fechaNode = fechaEnvioNodes.item(j); if (fechaNode.getNodeType() == Node.ELEMENT_NODE) { Element fechaElement = (Element) fechaNode; fechaEnvioList.add(fechaElement.getTextContent().trim()); } } datos.setFechaEnvio(fechaEnvioList); cabecera.setDatos(datos); listaCabeceras.add(cabecera); // 验证输出 System.out.println("id: " + cabecera.getId()); System.out.println("Tipo de mensaje: " + cabecera.getTipoMensaje()); System.out.println("Fecha de Envio列表: " + cabecera.getDatos().getFechaEnvio()); } }
注意事项
- 必须确保Java类补充了getter和setter方法,否则无法完成属性赋值。
- 可添加空值判断(比如检查
element.getElementsByTagName("id").item(0)是否为null),避免空指针异常,提升代码健壮性。 - 如果需要将字符串日期转换为Java 8的
LocalDateTime类型,可使用DateTimeFormatter解析:
此时DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; LocalDateTime dateTime = LocalDateTime.parse(fechaText, formatter);DatosRecepcion类的fechaEnvio属性需改为List<LocalDateTime>。
内容的提问来源于stack exchange,提问作者Jesus
相关产品推荐
相关产品推荐

