有没有办法使用 jackson API 解析带有标签元素属性的嵌套 XML,而无需创建 POJO?



我试图解析一个嵌套的XML,其中很少有嵌套元素具有属性。我在没有创建 POJO 的情况下使用了杰克逊 API(因为我必须创建 30+ 个 POJO 来存储来自 XML 的数据,所以我尝试不创建 POJO(,但我无法从 XML 中获取所有元素。它只选取 XML 文件中的最后一个元素。当我搜索原因时,我明白这是因为标签元素中的属性。

有没有办法解析带有属性的嵌套XML,而无需使用杰克逊API创建POJO?

下面是示例 XML:

<employee>
<id>1</id>
<name firstname="A" secondname="B">XYZ</name
<address>
<homeaddress city="NY" pincode="123">33rd Street</homeaddress>
<officeaddress city="NY" pincode="456">45th Street</officeaddress>
</address>
<id>2</id>
<name firstname="P" secondname="Q">PQR</name
<address>
<homeaddress city="NJ" pincode="123">Grrove</homeaddress>
<officeaddress city="NJ" pincode="456">Newark</officeaddress>
</address>
<id>3</id>
<name firstname="abc" secondname="def">asd</name
<address>
<homeaddress city="aa" pincode="234">Downtown</homeaddress>
<officeaddress city="aa" pincode="456">uptown</officeaddress>
</address>
</employee>

您可以使用增量/部分读取示例逐个标签读取XML。解决方案取决于要读取的值以及要跳过的值(如果有(。此外,这取决于您是否可以假设XML具有"稳定"格式,并且所有节点都以相同的顺序可用,并且即使对于空值也存在。在其他情况下,您需要编写更复杂的代码。例如,对于以下XML有效负载:

<employee>
<id>1</id>
<name firstname="A" secondname="B">XYZ</name>
<address>
<homeaddress city="NY" pincode="123">33rd Street</homeaddress>
<officeaddress city="NY" pincode="456">45th Street</officeaddress>
</address>
<id>2</id>
<name firstname="P" secondname="Q">PQR</name>
<address>
<homeaddress city="NJ" pincode="124">Grrove</homeaddress>
<officeaddress city="LA" pincode="789">Newark</officeaddress>
</address>
<id>3</id>
<name firstname="abc" secondname="def">asd</name>
<address>
<homeaddress city="AA" pincode="234">Downtown</homeaddress>
<officeaddress city="AB" pincode="456">uptown</officeaddress>
</address>
</employee>

使用版本2.10.1中的Jackson,我们可以读取上面的有效负载,如下所示:

import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class XmlMapperApp {
public static void main(String... args) throws Exception {
File xmlFile = new File("./resource/test.xml").getAbsoluteFile();
XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(new FileInputStream(xmlFile));
XmlMapper mapper = XmlMapper.xmlBuilder().build();
try (FromXmlParser parser = mapper.getFactory().createParser(reader)) {
while (parser.nextToken() != null) {
String id = readNext(parser, "id");
if (id == null) {
break;
}
String firstName = readNext(parser, "firstname");
String secondName = readNext(parser, "secondname");
String name = readNextValue(parser);
System.out.printf("ID='%s', NAME='%s %s %s'n", id, firstName, secondName, name);
String city = readNext(parser, "city");
String pinCode = readNext(parser, "pincode");
String homeAddress = readNextValue(parser);
System.out.printf("Home Address = '%s, %s %s'n", city, pinCode, homeAddress);
city = readNext(parser, "city");
pinCode = readNext(parser, "pincode");
homeAddress = readNextValue(parser);
System.out.printf("Office Address = '%s, %s %s'nn", city, pinCode, homeAddress);
}
}
}
private static String readNext(FromXmlParser parser, String name) throws IOException {
JsonToken token;
while ((token = parser.nextToken()) != null) {
switch (token) {
case FIELD_NAME:
String currentName = parser.currentName();
if (name.equals(currentName)) {
parser.nextToken();
return parser.getValueAsString();
}
break;
}
}
return null;
}
private static String readNextValue(FromXmlParser parser) throws IOException {
JsonToken token;
while ((token = parser.nextToken()) != null) {
switch (token) {
case VALUE_STRING:
return parser.getValueAsString();
}
}
return null;
}
}

上面的代码打印:

ID='1', NAME='A B XYZ'
Home Address = 'NY, 123 33rd Street'
Office Address = 'NY, 456 45th Street'
ID='2', NAME='P Q PQR'
Home Address = 'NJ, 124 Grrove'
Office Address = 'LA, 789 Newark'
ID='3', NAME='abc def asd'
Home Address = 'AA, 234 Downtown'
Office Address = 'AB, 456 uptown'

最新更新