是否有一种方法可以使用jackson API解析带有其标签元素中的属性的嵌套XML,而无需创建POJO?

问题描述 投票:0回答:1

我试图解析一个嵌套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>
java jackson xml-parsing pojo jackson-dataformat-xml
1个回答
0
投票

您可以使用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'
© www.soinside.com 2019 - 2024. All rights reserved.