我的xml内容如下:
<ParentClass>
<StringA>A</StringA>
<StringB>B</StringB>
<Items>
<Item ts="2016-03-25T20:00:00+02:00">1.17</Item>
<Item ts="2016-03-25T21:00:00+02:00">1.15</Item>
</Items>
</ParentClass>
我想阅读它,但我被困在正确的映射上。课程如下:
@XmlAccessorType(XmlAccessType.FIELD)
@NoArgsConstructor
@AllArgsConstructor
@Data
public class ParentClass {
@XmlElement(name = "StringA", required = true)
private String a;
@XmlElement(name = "StringB", required = true)
private String b;
@XmlElement(name = "Items", required = true)
private List<Item> consumptionList;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Item {
@XmlAttribute(name = "ts", required = true)
@XmlJavaTypeAdapter(value = LocalDateTimeAdapter.class)
private LocalDateTime timestamp;
private double value; //this corrensponds to 1.17 and 1.15 in xml
}
在实际文件中有100多个项目,当我读到它时,列表中只填充了一个Item类的实例,它的两个字段都为null。
我猜Item类中的映射都是错误的,但是尝试了所有,似乎没有任何工作。
我应该如何正确映射它以实现目标?
答案 0 :(得分:2)
您需要将@XmlValue
添加到字段value
,否则默认为@XmlElement
。
此外,您需要将consumptionList
上的注释更改为
@XmlElementWrapper(name = "Items")
@XmlElement(name = "Item", required = true)
另请注意,ts
值为OffsetDateTime
(或ZonedDateTime
)值,而不是LocalDateTime
,除非您LocalDateTimeAdapter
应用了某个时区,例如: JVM默认时区。
我发现帮助正确应用@Xml...
注释的最佳方法是创建对象并将它们编组为XML以查看您获得的内容。您当前的代码将创建此XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ParentClass>
<StringA>A</StringA>
<StringB>B</StringB>
<Items ts="2016-03-25T20:00:00+02:00">
<value>1.17</value>
</Items>
<Items ts="2016-03-25T21:00:00+02:00">
<value>1.15</value>
</Items>
</ParentClass>
如果您应用上述更改,则会获得:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ParentClass>
<StringA>A</StringA>
<StringB>B</StringB>
<Items>
<Item ts="2016-03-25T20:00:00+02:00">1.17</Item>
<Item ts="2016-03-25T21:00:00+02:00">1.15</Item>
</Items>
</ParentClass>
以上输出是通过添加以下代码创建的:
class LocalDateTimeAdapter extends XmlAdapter<String, LocalDateTime> {
@Override
public String marshal(LocalDateTime time) throws Exception {
return time.atZone(ZoneOffset.ofHours(2))
.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssxxx"));
}
@Override
public LocalDateTime unmarshal(String text) throws Exception {
return ZonedDateTime.parse(text).toLocalDateTime();
}
}
public static void main(String... args) throws Exception {
ParentClass p = new ParentClass("A", "B", Arrays.asList(
new Item(LocalDateTime.parse("2016-03-25T20:00:00"), 1.17),
new Item(LocalDateTime.parse("2016-03-25T21:00:00"), 1.15)));
JAXBContext jaxbContext = JAXBContext.newInstance(ParentClass.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(p, System.out);
}