java - 将 XML 解析为 Java 对象节点
问题描述
目前我在尝试将 xml 文档解析为 Java 对象时遇到问题。我想保留的唯一必要信息是iid和时间列表。
xml测试文件:
<items>
<item>
<iid>14</iid>
<options>
<option>
<times>
<time>
<timeentry>20200714100100</timeentry>
<timetill>20200714101500</timetill>
<timemaxcount>2</timemaxcount>
</time>
<time>
<timeentry>20200714101600</timeentry>
<timetill>20200714103000</timetill>
<timemaxcount>2</timemaxcount>
</time>
<time>
<timeentry>20200714103100</timeentry>
<timetill>20200714104500</timetill>
<timemaxcount>2</timemaxcount>
</time>
<time>
<timeentry>20200714104600</timeentry>
<timetill>20200714110000</timetill>
<timemaxcount>2</timemaxcount>
</time
</option>
</options>
</item>
</items>
我创建了两个包含 iid 和时间列表的 Java 对象类。解析 xml 文件时,只有字段 iid 被填充并且列表对象为空。我错过了什么?
@JsonIgnoreProperties(ignoreUnknown = true)
@XmlRootElement(name = "item")
@JacksonXmlRootElement(localName = "item")
public class SubProduct implements Serializable {
private String iid;
@JacksonXmlElementWrapper(localName = "times")
@JacksonXmlProperty(localName = "time")
private List<TimePeriod> times;
}
@JsonIgnoreProperties(ignoreUnknown = true)
@JacksonXmlRootElement(localName = "time")
public class TimePeriod implements Serializable {
@JsonProperty(value = "timeentry")
String timeEntry;
@JsonProperty(value = "timetill")
String timeTill;
@JsonProperty(value = "timemaxcount")
String timeMaxCount;
}
服务层:
...
NodeList itemList = document.getElementsByTagName("item");
List<SubProduct> subProducts = new ArrayList<>();
for (int i = 0; i < nodes.getLength(); i++) {
SubProduct value = xmlMapper.readValue(nodeToString(nodes.item(i)), SubProduct.class);
subProducts.add(value);
}
return subProducts;
...
public static String nodeToString(Node node) throws Exception{
StringWriter sw = new StringWriter();
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(node), new StreamResult(sw));
return sw.toString();
}
回应:
{
"iid": "9",
"times": null
},
解决方案
你不需要混合Jackson
或JAXB
上课Transformer
。您可以直接将给定XML
的有效负载反序列化为POJO
模型。items
,options
和times
节点代表List
节点。我们可以将其映射到以下模型:
@Data
@ToString
class Item {
private int iid;
private List<Option> options;
}
@Data
@ToString
class Option {
private List<Time> times;
}
@Data
@ToString
class Time {
@JsonFormat(pattern = "yyyyMMddHHmmss")
@JsonProperty("timeentry")
private LocalDateTime entry;
@JsonFormat(pattern = "yyyyMMddHHmmss")
@JsonProperty("timetill")
private LocalDateTime till;
@JsonProperty("timemaxcount")
private int maxCount;
}
我使用Lombok注释来避免样板代码。简单用法:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.Data;
import lombok.ToString;
import java.io.File;
import java.time.LocalDateTime;
import java.util.List;
public class XmlMapperApp {
public static void main(String... args) throws Exception {
File xmlFile = new File("./resource/test.xml").getAbsoluteFile();
XmlMapper mapper = XmlMapper.xmlBuilder()
.addModule(new JavaTimeModule())
.build();
List<Item> items = mapper.readValue(xmlFile, new TypeReference<List<Item>>() {
});
items.forEach(item -> {
System.out.println("Id => " + item.getIid());
System.out.println("Times => ");
item.getOptions().stream().flatMap(o -> o.getTimes().stream())
.forEach(System.out::println);
});
}
}
上面的代码打印:
Id => 14
Times =>
Time(entry=2020-07-14T10:01, till=2020-07-14T10:15, maxCount=2)
Time(entry=2020-07-14T10:16, till=2020-07-14T10:30, maxCount=2)
Time(entry=2020-07-14T10:31, till=2020-07-14T10:45, maxCount=2)
Time(entry=2020-07-14T10:46, till=2020-07-14T11:00, maxCount=2)
也可以看看:
推荐阅读
- unity3d - 将位图转换为 Texture2D 会导致统一崩溃
- apache - 从 access.log 获取前 50 个 IP,包括 IPV6
- bash - .bashrc 末尾的“源”语句和“函数”声明相互干扰
- swift - UIWebview 约束未调整
- python - SQLAlchemy 加入渴望加载不起作用
- javascript - 如何使用 javascript 将图像插入 div?
- c# - 如何防止重复以返回结尾的代码块?
- c - 执行此程序时,我的 4*4 矩阵中的 8 自动变为 0
- installation - 在 OPAM 中安装软件包列表
- node.js - 无法在 mongodb atlas UI 中保存后期模型