Как я могу игнорировать некоторые элементы при чтении XML с помощью Jackson/FasterXML?

Я хочу пропустить все узлы, кроме first_name, node100 и его дочерних элементов. У меня есть этот XML (на самом деле у меня много сотрудников, и каждый тег сотрудника имеет много узлов):

 <employees>
        <employee>
            <first_name>John</first_name>
            <last_name>Doe</last_name>
            <age>26</age>
        </employee>
        <employee>
            <first_name>Peter</first_name>
            <last_name>Parker</last_name>
            <age>30</age>
        </employee>
    </employees>

Я могу читать с помощью Jackson FasterXML. Я создал 2 POJOS для сопоставления структуры XML выше.

  @JacksonXmlRootElement(localName = "employees") public final class Employees {
        @JacksonXmlElementWrapper(localName = "employee", useWrapping = false)
        private Employee[] employee;
//ommiteed getter and setters

public final class Employee {
    @JacksonXmlProperty(localName = "id", isAttribute = true)
    private String id;
    @JacksonXmlProperty(localName = "first_name")
    private String firstName;
    @JacksonXmlProperty(localName = "last_name")
    private String lastName;
    @JacksonXmlProperty(localName = "age")
    private int age;

Теперь в производстве xml имеет 1000 узлов внутри узла.

<employee>
                <first_name>John</first_name>
                <last_name>Doe</last_name>
                <age>26</age>
                <node1>  </node1>
                <node2>  </node2>

                ..

                <node100> 
                   <values> 
                  <value> val1 </value>
                  <value> val1 </value>
                  <value> val1 </value>
                  <value> val1 </value>
                  </node100> 

            </employee>


    <node100>  is also inside 4-5 nodes (which i have not shown above).

Итак, мой вопрос в том, как я могу просто прочитать first_name , last_name и tag . Какой должна быть структура моего класса POJO?

Код для преобразования XML в POJO

System.out.println( " hello");
ObjectMapper objectMapper = new XmlMapper();
// Reads from XML and converts to POJO
Employees employees = objectMapper.readValue(
        StringUtils.toEncodedString(Files.readAllBytes(Paths.get("C:\\Users\\91895\\Downloads\\File\\XmlFile.xml")), StandardCharsets.UTF_8),
        Employees.class);
System.out.println(employees);

person Pale Blue Dot    schedule 29.09.2019    source источник
comment
как я могу просто прочитать имя, фамилию и тег - Что вы передаете по тегу?   -  person mentallurg    schedule 29.09.2019
comment
Под тегом я подразумеваю узел.   -  person Pale Blue Dot    schedule 29.09.2019
comment
Если вы хотите прочитать также элементы node, это означает, что вы хотите прочитать все. Но ваши слова просто прочитал означают, что вы хотели пропустить некоторые элементы. Что именно вы хотите прочитать, а что пропустить?   -  person mentallurg    schedule 29.09.2019
comment
Да, вы правы, я не правильно сформулировал вопрос. Я хочу пропустить все узлы, кроме first_name, node100 и его дочерних элементов. Итак, как я могу создать свой класс POJO?   -  person Pale Blue Dot    schedule 29.09.2019


Ответы (1)


В вашем классе определите элементы, которые вы хотите прочитать из XML. Чтобы игнорировать другие элементы, настройте ObjectMapper соответствующим образом:

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
person mentallurg    schedule 29.09.2019
comment
спасибо, это то, что я искал. Только одно сомнение в том, что я читаю файл правильно? Поскольку я не хочу загружать весь файл сразу в память. Это огромный файл. - person Pale Blue Dot; 29.09.2019
comment
Чтобы я не хотел сразу загружать весь файл в память - для этого можно использовать разные приемы. Например, вы можете реализовать свой собственный SAXParser или использовать потоковый API (см. пример здесь). Затем у вас есть контроль, когда создавать дополнительные элементы или нет. - person mentallurg; 29.09.2019
comment
objectMapper.readValue( StringUtils.toEncodedString(Files.readAllBytes(Paths.get("C:\\Users\\91895\\Downloads\\File\\XmlFile.xml")), StandardCharsets.UTF_8), Employees.class); Итак, вы говорите, что в настоящее время я загружаю весь файл сразу. И мне следует использовать потоковый API с Джексоном? Ваш API потоковой передачи (см. пример здесь) не работает. - person Pale Blue Dot; 29.09.2019
comment
Нет. Streaming API вместо Jackson. Файл будет прочитан до конца. Но у вас будет возможность решить, что, например, вы создаете только 5 объектов и можете просто игнорировать любые дальнейшие вхождения объектов. - person mentallurg; 29.09.2019
comment
Если у вас есть большой файл, например 1 ТБ, и вы хотите прочитать только первые 100 КБ, вы также можете реализовать свой собственный InputStream, который останавливается после чтения 100 КБ. Конечно, вы должны правильно реагировать на соответствующие исключения. - person mentallurg; 29.09.2019
comment
хорошо, stax будет более подробным и подверженным ошибкам. Вот почему я предпочитаю использовать JACKSON - person Pale Blue Dot; 29.09.2019