我试图解析一个嵌套XML,其中很少有嵌套元素具有属性。我使用了杰克逊API而不创建POJO(因为必须创建30多个POJO才能存储来自XML的数据,所以我尝试不创建POJO),但是我无法从XML中获取所有元素。它仅选择XML文件中的最后一个元素。当我搜索原因时,我了解到这是由于标签元素中的属性。
是否有一种方法可以解析带有属性的嵌套XML,而无需使用jackson 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>
您可以使用Incremental/partial reading示例逐个读取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>
使用版本Jackson
中的2.10.1
,我们可以如下读取上述有效负载:
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'\n\n", 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'