【发布时间】:2019-12-09 08:24:28
【问题描述】:
我想构建一个解析器来解析Java 中的XML 文件。
正如您在下面的代码中看到的,我使用LinkedHashMap 来访问所需的值First、Middle 和Last。
我的问题是我的NameList 标签包含多个Person 标签,而LinkedHashMap 到目前为止只给了我最后一个Person,在我的示例中(输出):
given: Ghi
family: Tom
given: Jkl
family: Mary
如何使用LinkedHashMap 的方法访问其他两个(Karl Abc、Thomas Def)?
这是我的XML 文件:
<Sources>
<Source>
<Year>2019</Year>
</Source>
<Source>
<Title>Blablabla</Title>
<Author>
<BookAuthor>
<NameList>
<Person>
<Last>Karl</Last>
<First>Abc</First>
</Person>
<Person>
<Last>Thomas</Last>
<First>Def</First>
</Person>
<Person>
<Last>Tom</Last>
<First>Ghi</First>
</Person>
</NameList>
</BookAuthor>
</Author>
</Source>
<Source>
<Author>
<Editor>
<NameList>
<Person>
<Last>Mary</Last>
<First>Jkl</First>
</Person>
</NameList>
</Editor>
</Author>
</Source>
这是我的代码:
private static void XmlFileParser() throws IOException {
InputStream xmlFile = Publication.class.getClassLoader().getResourceAsStream("test.xml");
ObjectMapper mapper = new XmlMapper();
// Configure
mapper
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
Object[] deserializedData = mapper.readValue(xmlFile, Object[].class);
for (Object element : deserializedData) {
if (element instanceof LinkedHashMap) {
LinkedHashMap<String, Object> el = (LinkedHashMap<String, Object>) element;
if ((el.get("Author")) == null) {
continue;
} else {
// Last -> family
// First, Middle -> given
if (((LinkedHashMap) el.get("Author")).get("Author") instanceof LinkedHashMap && ((((LinkedHashMap) ((LinkedHashMap) el
.get("Author")).get("Author")).get("NameList")) != null)) {
Object first = ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) el.get(
"Author")).get("Author")).get("NameList")).get("Person")).get("First");
Object middle = ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) el.get(
"Author")).get("Author")).get("NameList")).get("Person")).get("Middle");
if (first != null || middle != null) {
System.out.println("given: " + evaluateGiven(first, middle));
}
Object family = ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) el.get(
"Author")).get("Author")).get("NameList")).get("Person")).get("Last");
System.out.println("family: " + family);
} else if (((LinkedHashMap) el.get("Author")).get("Editor") instanceof LinkedHashMap && ((((LinkedHashMap) ((LinkedHashMap) el
.get("Author")).get("Editor")).get("NameList")) != null)) {
Object first = ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) el.get(
"Author")).get("Editor")).get("NameList")).get("Person")).get("First");
Object middle = ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) el.get(
"Author")).get("Editor")).get("NameList")).get("Person")).get("Middle");
if (first != null || middle != null) {
System.out.println("given: " + evaluateGiven(first, middle));
}
Object family = ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) ((LinkedHashMap) el.get(
"Author")).get("Editor")).get("NameList")).get("Person")).get("Last");
System.out.println("family: " + family);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
我的助手类:
private static String evaluateGiven(Object first, Object middle) {
if (first == null) {
first = "";
} else if (middle == null) {
middle = "";
}
return first.toString() + " " + middle.toString();
}
由于我的代码很炸,你知道如何让它更小吗?
如果能得到一些帮助,我会很高兴的。
谢谢!
【问题讨论】:
-
既然你使用jackson xml,为什么不把xml转换成一个自定义对象,由具有给定属性的类表示呢?
-
如果您的目标是将 XML 转换为 POJO,请使用 JAXB API,它会小心地将 XML 转换为 Java 或 Java 转换为 XML。
-
你最近问了一个类似的问题:How to deserealize multiple nested elements in Jackson?。为什么使用
LinkedHashMap?您可以使用上一个问题的解决方案或创建POJO并反序列化给定XML。 -
@MichałZiober 我被困在挑战中,只能在标签中获取多个
Person标签中的最后一个Person标签(就像标签NameList中的许多Persons一样。所以我决定尝试使用LinkedHashMap的新方法。您对如何获取所有Person标签有什么建议吗?
标签: java xml parsing jackson linkedhashmap