Есть ли способ проанализировать вложенные XML с атрибутами в его элементах тегов, используя jackson API, не создавая POJO? - PullRequest
0 голосов
/ 10 февраля 2020

Я пытался проанализировать вложенный XML, где немногие из вложенных элементов имеют атрибуты. Я использовал API-интерфейсы Джексона без создания POJO (поскольку мне нужно было создать более 30 POJO для хранения данных из XML, поэтому я пытался без создания POJO), но я не могу получить все элементы из XML. Он выбирает только последний элемент в файле XML. Когда я искал причину, я понял, что это из-за атрибутов в элементах тега.

Есть ли способ проанализировать вложенные XML с атрибутами без создания POJO с помощью API-интерфейса jackson?

Вот пример 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>

1 Ответ

0 голосов
/ 11 февраля 2020

Вы можете использовать Пример приращения / частичного чтения , чтобы прочитать 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'
...