Рубрики
Без рубрики

Чтение и запись XML на Java

Автор оригинала: Vasyl Lagutin.

Что такое XML?

Аббревиатура “XML” расшифровывается как – e X tensible M arkup L ангаж. Он имеет структуру разметки, аналогичную HTML, и был разработан для хранения и транспортировки данных. Он определяет набор правил, которые делают его как человеком, так и машиночитаемым.

Несмотря на то, что это язык разметки, такой как HTML, XML обычно используется для обмена данными между веб-службами, серверной частью и интерфейсами, так же, как JSON , и считается его предшественником.

Если вам интересно прочитать о чтении и написании JSON на Java , мы уже обсудили это!

Важно отметить, что XML не имеет предопределенного набора тегов, таких как HTML, а скорее определяется пользователем. Именно эта гибкость привела к созданию нескольких форматов документов, таких как RSS , Atom , SOAP и XHTML . Все эти форматы, по сути, являются подмножествами XML.

Давайте рассмотрим простой XML-документ, который копирует тот же объект, который мы использовали ранее в отношении JSON:



    31
    
        Football
        Swimming
    
    true
    
        
            5
            Billy
        
        
            3
            Milly
        
    
    Benjamin Watson

Ключевое различие между XML и JSON заключается в том, что мы определяем этот файл с версией XML и кодировкой в начале документа с помощью тега . Еще одно отличие состоит в том, что каждое свойство объекта должно быть заключено в свой собственный тег – <возраст>31 . Элементы массива нельзя указать без тега, поэтому для их перечисления мы завершаем их с помощью <элемент>... в теге <хобби>... .

ДЖАКСБ

Поскольку XML-это текстовый формат, вы можете использовать для его чтения и записи те же методы, что и для любого другого текстового файла.

Java, однако, предоставляет удобный способ манипулирования XML с использованием структуры, называемой J ava A архитектура для X ML B inding, или JAXB для краткости. Это позволяет нам сопоставлять объекты Java с XML-документами и наоборот. JAXB был впервые представлен в JDK 1.6 и недоступен в предыдущих версиях.

Поскольку JAXB является стандартной платформой JDK, нет необходимости включать какие-либо внешние зависимости в проект для JDK 1.6+.

Примечание: Однако, если вы используете Java 9 или выше, вам следует включить дополнительный параметр в команду javac . Если вы используете среду разработки, такую как IntelliJ IDEA или Eclipse, найдите дополнительные параметры компилятора и убедитесь, что в нее включена строка --add-modules java.xml.bind .

В случае IntelliJ IDEA он находится в Предпочтения -> Сборка, выполнение, Развертывание -> Компилятор – > Компилятор Java меню.

Если вы все еще будете получать ошибки, такие как Исключение в потоке "основной" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBContext даже после добавления дополнительной опции компилятора добавьте следующие зависимости Maven:


    javax.xml.bind
    jaxb-api
    2.2.11


    com.sun.xml.bind
    jaxb-core
    2.2.11


    com.sun.xml.bind
    jaxb-impl
    2.2.11


    javax.activation
    activation
    1.1.1

Основные концепции JAXB называются Маршалинг и Немаршалинг . Неудивительно, что они представлены классами Маршаллер и Немаршаллер .

Сортировка-это процесс преобразования объектов Java в XML, а разбиение-это процесс преобразования XML в объекты Java.

JAXB настраивается с использованием аннотаций, импортированных из пакета javax.xml.bind.annotations .

Давайте определим класс Java, который представляет человека, описанного в нашем XML-документе:

@XmlRootElement
public class Person {

    public Person(String name, int age, boolean isMarried, List hobbies, List kids) {
        this.name = name;
        this.age = age;
        this.isMarried = isMarried;
        this.hobbies = hobbies;
        this.kids = kids;
    }

    public Person(String name, int age) {
        this(name, age, false, null, null);
    }

    private String name;
    private Integer age;
    private Boolean isMarried;
    private List hobbies;
    private List kids;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isMarried() {
        return isMarried;
    }

    @XmlElement(name = "isMarried")
    public void setMarried(boolean married) {
        isMarried = married;
    }

    @XmlElementWrapper(name = "hobbies")
    @XmlElement(name = "element")
    public List getHobbies() {
        return hobbies;
    }

    public void setHobbies(List hobbies) {
        this.hobbies = hobbies;
    }

    public List getKids() {
        return kids;
    }

    @XmlElementWrapper(name = "kids")
    @XmlElement(name = "person")
    public void setKids(List kids) {
        this.kids = kids;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", isMarried=" + isMarried +
                ", hobbies=" + hobbies +
                ", kids=" + kids +
                '}';
    }
}

@XmlRootElement – сопоставляет класс или тип перечисления с элементом XML. Он описывает корневой элемент XML-документа и должен быть указан в объявлении Person class.

@XmlElementWrapper – создает элемент оболочки вокруг представления XML, в нашем случае Список . Элементы списка должны быть указаны явно с помощью аннотации @XmlElement .

@XmlElement – сопоставляет свойство из объекта Java с элементом XML, производным от имени свойства. Чтобы указать другое имя свойства XML, мы включаем его в качестве строкового параметра в объявление аннотации, т. е. (имя) .

Без промедления

Самый простой пример метода сортировки потребует от нас создания экземпляра JAXBContext , передающего Person.class в качестве единственного входного параметра его конструктора.

Затем unmarshaller создается путем вызова метода createUnmarshaller () , и экземпляр фактического Человека создается его unmarshal() методом.

Обязательно используйте явную типизацию, так как unmarshal метод возвращает объект типа:

Git Essentials

Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!

public class Solution {
    public static void main(String[] args) throws Exception {
        Person person = XMLtoPersonExample("person.xml");
        System.out.println(person);
    }

    private static Person XMLtoPersonExample(String filename) throws Exception {
        File file = new File(filename);
        JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        return (Person) jaxbUnmarshaller.unmarshal(file);
    }
}

После запуска этого кода вы должны увидеть что-то вроде:

Person{name='Benjamin Watson', age=31, isMarried=true, hobbies=[Football, Swimming], kids=[Person{name='Billy', age=5, isMarried=null, hobbies=null, kids=null}, Person{name='Milly', age=3, isMarried=null, hobbies=null, kids=null}]}

Сортировка

Чтобы продемонстрировать способность JAXB писать XML-файл, используя объект Java в качестве источника, мы добавим следующий метод:

private static void personToXMLExample(String filename, Person person) throws Exception {
    File file = new File(filename);
    JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);

    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    jaxbMarshaller.marshal(person, file);
    jaxbMarshaller.marshal(person, System.out);
}

Это очень похоже на предыдущий пример и включает в себя повторное создание JAXBContext . На этот раз процесс пойдет в обратном направлении, и выходные данные XML будут записаны в файл и консоль.

Добавив вызов этого метода в качестве последней строки в Solution.main() как:

personToXMLExample("person-output.xml", person);

и запустив его, мы получим досадное исключение.

Exception in thread "main" java.lang.NullPointerException
    at com.stackabuse.xml.Person.isMarried(Person.java:49)
    at com.stackabuse.xml.Person$JaxbAccessorM_isMarried_setMarried_boolean.get(MethodAccessor_Boolean.java:61)
...

Мы допустили ошибку , установив тип поля isMarried в класс-оболочку Boolean и возвращаемый тип геттера isMarried() в примитивный логический , что приводит к тому, что JAXB пытается распаковать null и в результате выдает Исключение NullPointerException .

Быстрое и простое решение этой проблемы состояло бы в том, чтобы выровнять эти два значения либо логическое , либо Логическое .

После устранения проблемы мы получим следующие выходные данные как для консоли, так и для файла:



    31
    
        Football
        Swimming
    
    
        
            5
            Billy
        
        
            3
            Milly
        
    
    true
    Benjamin Watson

Как мы видим, он полностью идентичен исходному XML-файлу, который мы собрали в объект person .

Вывод

Чтение и запись XML на Java можно легко выполнить с помощью платформы JAXB. Используя аннотации, мы определяем правила сопоставления между классами Java и XML-документами, представляющими их объекты.

XML часто считается устаревшим форматом, который уступает JSON. Однако знание того, как читать и писать его с помощью Java, является полезным навыком для любого разработчика программного обеспечения, поскольку многие службы в Интернете все еще используют его и еще не имеют API JSON. Это также относится ко многим форматам файлов, которые хранят данные в файлах в формате XML.

Хотя, если вам больше нравится JSON, я бы посоветовал почитать о чтении и записи JSON на Java, мы тоже об этом позаботились!