Как записать в xml файл в java

Обновлено: 07.07.2024

Это пособие для программистов знакомит с XML и его использованием с Java, статью подготовил Ларс Фогель, переведено нами на русский язык.

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

  • XML-документ всегда начинается с пролога
  • Каждый открывающий тег имеет закрывающий тег.
  • Все теги полностью вложены.

Правильный XML-файл должен содержать ссылку на XML-схему и быть действительным в соответствии с этой схемой. Ниже приведен правильный, корректный XML-файл.

Сравнение XML с другими форматами

Обрабатывать XML-документ относительно легко по сравнению с двоичным или неструктурированным форматом. Это из-за следующих характеристик:

  • простой текст
  • представляет данные без определения способа отображения данных
  • может быть преобразован в другие форматы через XSL
  • может быть легко обработан с помощью стандартных анализаторов
  • XML-файлы являются иерархическими

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

Элементы XML

Тег, который не содержит никакого содержимого, называется «пустым тегом», например, .
Комментарии в XML определяются как: <! COMMENT>.

Обзор XML Java

Язык программирования Java содержит несколько методов для обработки и написания XML.
Более старые версии Java поддерживали только API DOM (объектная модель документа) и API SAX (простой API для XML).

В DOM вы получаете доступ к документу XML через дерево объектов. DOM может использоваться для чтения и записи файлов.

Ниже объясняется интерфейс Stax.

Потоковый API для XML (StaX)

Ядро StaX API делится на две категории, и они перечислены ниже.

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

API Event Iterator

API итератора событий имеет два основных интерфейса: XMLEventReader для синтаксического анализа XML и XMLEventWriter для генерации XML.

Определим следующий класс для хранения отдельных записей.

Далее читается файл XML и создается список элементов объекта из записей.

Вы можете проверить парсер с помощью следующей тестовой программы. Обратите внимание, что файл config.xml должен существовать в папке проекта Java.

Пример записи файла XML

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

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим - напишите комментарий, добавьте информации к статье.

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

Основы XML для Java программиста - Часть 1 из 3 - 1

Вступление

Основы XML для Java программиста - Часть 1 из 3 - 2

Для более ясного объяснения, правильней будет визуализировать XML примером. HTML и XML похожи синтаксисом, так как у них общий родитель – SGML. Однако, в HTML есть только фиксированные теги конкретного стандарта, в то время, как в XML вы можете создавать свои собственные теги, атрибуты и, в целом, делать все, что захотите, чтобы хранить данные так, как вам будет удобно. По сути, XML файлы может прочитать любой человек, знающий английский язык. Изобразить данный пример можно с помощью дерева. Корень дерева – Company. Он же – корневой (рут) элемент, от которого идут все остальные элементы. В каждом XML файле может быть только один рут элемент. Он должен объявляться после декларации xml файла (первая строчка в примере) и вмещать в себе все другие элементы. Немного о декларации: она обязательная и нужна для идентификации документа как XML. У неё есть три псевдо-атрибуты (специальные предопределенные атрибуты): version (по стандарту 1.0), encoding (кодировка) и standalone (автономность: если yes и к документу подключаются внешние схемы, то будет ошибка, по умолчанию - no). Элементы – это сущности, которые хранят данные с помощью других элементов и атрибутов. Атрибуты – это дополнительная информация об элементе, которая указывается при добавлении элемента. Если перевести объяснение на ООП-поле, то можно привести такой пример: у нас есть машина, у каждой машины есть характеристики (цвет, вместимость, марка и другое) – это атрибуты, и есть сущности, которые внутри машины: двери, окна, двигатель, руль – это другие элементы. Хранить свойства можно как и отдельными элементами, так и атрибутами в зависимости от вашего желания. Как никак, XML – крайне гибкий формат хранения информации про что-либо. После объяснений, нам достаточно разобрать пример выше, чтобы все встало на свои места. В примере мы описали простую структуру компании: есть компания, у которой есть имя и офисы, а в офисах есть сотрудники. Элементы Employees и Offices – элементы-обертки – они служат для того, чтобы собрать в себе элементы одного вида, по сути, соединив их в одно множество для удобства их обработки. Отдельного внимания заслуживают floor и room. Это – атрибуты офиса (этаж и номер), другими словами – его свойства. Если бы у нас был элемент «картинка», то можно было бы передавать её размеры. Вы можете заметить, что у компании нет атрибута name, но есть элемент name. Просто вы можете описывать структуры так, как захотите. Никто не обязывает вас все свойства элементов записывать только в атрибуты, вы можете использовать и просто элементы и записывать внутри них какие-то данные. Например, мы можем записывать имя и должность наших работников, как атрибуты: Как вы видите, теперь имя и должность каждого работника – это его атрибуты. И можно заметить, что внутри сущности (тега) employee ничего нет, все элементы employee – пустые. Тогда можно сделать employee пустым элементом – закрыть его сразу после объявления атрибутов. Это делается довольно просто, достаточно просто поставить слэш: Как вы можете заметить, закрыв пустые элементы мы сохранили всю целостность информации и намного сократили запись, сделав информацию более сжатой и читабельной. Для того, чтобы добавить комментарий (текст, который будет пропускаться при парсинге файла) в XML, есть следующий синтаксис: И последняя конструкция – это CDATA, означает «символьные данные». Благодаря данной конструкции, можно записывать текст, который не будет интерпретироваться как разметка XML. Это полезно, если внутри XML файла у вас есть сущность, которая хранит в информации XML разметку. Пример: Особенность XML в том, что вы можете расширять его так, как захотите: использовать свои элементы, свои атрибуты и структурировать его по своему желанию. Вы можете использовать для хранения данных как атрибуты, так и элементы (как это было показано в примере ранее). Однако нужно понимать, что придумывать свои элементы и атрибуты на ходу и как вы захотите вы можете, но что, если вы будете работать на проекте, где другой программист захочет перенести элемент name в атрибуты, а у вас вся логика программы написана так, чтобы name был элементом? Как же создать свои собственные правила того, какие элементы должны быть, какие атрибуты у них есть и другие вещи, чтобы можно было проводить валидацию XML файлов и быть уверенным, что правила станут стандартными в вашем проекте и никто их нарушать не будет? Для того, чтобы написать все правила вашей собственной XML разметки, есть специальные средства. Самые известные: DTD и XML Schema. В этой статье будет только про первое.

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

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

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

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

ДЖАКСБ

Поскольку 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 .

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

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

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

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

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

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

Сортировка

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

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

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

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

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

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

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

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

Вывод

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

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

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

Screenshot AddressApp Part 5

В данный момент, все данные об адресатах могут находиться исключительно в памяти. Каждый раз, когда мы закрываем адресную книгу, они теряются. Самое время подумать о постоянном хранении данных.

Сохранение пользовательских настроек

Благодаря классу Preferences , Java позволяет сохранять некоторую информацию о состоянии приложения. В зависимости от операционной системы, Preferences сохраняются в различных местах (например, в файле реестра Windows).

Мы не можем использовать класс Preferences для сохранения всей адресной книги. Но он позволяет сохранять некоторые простые настройки приложения, например, путь к последнему открытому файлу. Имея эти данные, после перезапуска приложения мы всегда сможем восстанавливать состояние нашего приложения.

Следующие два метода обеспечивают сохранение и восстановление настроек нашего приложения. Добавьте их в конец класса MainApp :

MainApp.java

Хранение данных в XML

Почему именно XML?

Один из наиболее распространённых способов хранения данных, это использование баз данных. В то время, как данные, которые мы должны хранить, являются объектами, базы данных содержат их в виде реляционных данных (например, таблиц). Это называется объектно-реляционное рассогласование импендансов. Для того, чтобы привести наши объектные данные в соответствие с реляционными таблицами, требуется выполнить дополнительную работу. Существуют фреймворки, которые помогают приводить объектные данные в соответствие с реляционной базой данных (Hibernate - один из наиболее популярных), но чтобы начать их использовать, также необходимо проделать дополнительную работу и настройку.

Для нашей простой модели данных намного легче хранить данные в виде XML. Для этого мы будем использовать библиотеку JAXB (Java Architechture for XML Binding). Написав всего несколько строк кода, JAXB позволит нам сгенерировать примерно такой XML-файл:

Пример сгенерированного XML-файла

Использование JAXB

Библиотека JAXB уже включена в JDK. Это значит, что никаких дополнительных библиотек подключать не придётся.

JAXB предоставляет две основные функции: способность к маршаллированию объектов Java в XML и обратную демаршализацию из xml-файла в объекты Java.

Для того, чтобы с помощью JAXB можно было выполнять подобные преобразования, нам необходимо подготовить нашу модель.

Подготовка класса-модели для JAXB

Данные, которые мы хотим сохранять, находятся в переменной personData класса MainApp . JAXB требует, чтобы внешний класс наших данных был отмечен аннотацией @XmlRootElement (только класс, поле этой аннотацией пометить нельзя). Типом переменной personData является ObservableList , а его мы не можем аннотировать. Для того, чтобы разрешить эту ситуацию, необходимо создать класс-обёртку, который будет использоваться исключительно для хранения списка адресатов, и который мы сможем аннотировать как @XmlRootElement .

Создайте в пакете ch.makery.address.model новый класс PersonListWrapper .

PersonListWrapper.java

Обратите внимание на две аннотации:

  • @XmlRootElement определяет имя корневого элемента.
  • @XmlElement это необязательное имя, которое мы можем задать для элемента.

Чтение и запись данных с помощью JAXB

Сделаем наш класс MainApp ответственным за чтение и запись данных нашего приложения. Для этого добавьте в конец класса MainApp.java два метода:

Маршаллинг и демаршализация готовы. Теперь для того, чтобы использовать новый функционал, давайте создадим пункты меню для сохранения и загрузки.

Обработка действий меню

Мы уже создавали меню в файле RootLayout.fxml , но пока не использовали его. Перед тем, как мы добавим в наше меню поведение, давайте создадим в нём все необходимые пункты.

В приложении Scene Builder откройте файл RootLayout.fxml и перенесите необходимое количество пунктов меню (MenuItem) из вкладки Library на вкладку Hierarchy. Создайте следующие пункты меню: New, Open…, Save, Save as… и Exit.

Add Menu Items

Подсказка: для установки на пункты меню горячих клавиш спользуйте свойство Accelerator во вкладке Properties.

Класс RootLayoutController

Для обработки поведения меню нам необходим ещё один класс-контроллер. В пакете ch.makery.address.view создайте класс RootLayoutController .

Добавьте новому классу-контроллеру следующее содержание:

RootLayoutController.java

Компонент FileChooser

Обратите внимание на методы в классе RootLayoutController , которые используют компонент FileChooser . Сперва мы создаём новый экземпляр класса FileChooser . Потом применяем фильтр расширения - при выборе файлов будут показываться только те, которые имеют расширение .xml . Ну и наконец, мы отображаем данный компонент выше PrimaryStage.

Если пользователь закрывает диалог выбора файлов ничего не выбрав, то возвращается null . В противном случае мы берём выбранный файл и передаём его в методы loadPersonDataFromFile(. ) или savePersonDataToFile(. ) , которые находятся в классе MainApp.

Связывание fxml-представления с классом-контроллером

В приложении Scene Builder откройте файл RootLayout.fxml . Во вкладке Controller в качестве класса-контроллера выберите значение RootLayoutController .

Menu Actions

Перейдите на вкладку Hierarchy и выберите пункт меню. Во вкладке Code в качестве значений свойства On Action вы можете увидеть все доступные методы выбранного класса-контроллера. Выберите метод, соответствующий данному пункту меню.

Повторите предыдущий шаг для каждого пункта меню.

Закройте приложение Scene Builder и обновите проект (нажмите Refresh (F5) на корневой папке вашего проекта). Это позволит среде разработки Eclipse “увидеть” изменения, сделанные в приложении Scene Builder.

Связывание главного класса с классом RootLayoutController

В некоторых местах кода классу RootLayoutController требуется ссылка на класс MainApp . Эту ссылку мы ещё пока не передали.

Откройте класс MainApp и замените метод initRootLayout() следующим кодом:

Обратите внимание на два изменения: на строки, дающие доступ контроллеру к главному классу приложения и на три последних строки для загрузки последнего открытого файла с записями.

Тестирование

Устроив небольшой тест-драйв своему приложению убедитесь, что вы уже можете использовать меню для сохранения информации об адресатах в файл.

Когда вы откроете xml -файл в текстовом редакторе, то вместо значения дня рождения увидите пустой тег <birthday/> . Дело в том, что JAXB не знает как преобразовать тип LocalDate в XML. Чтобы определить процесс преобразования, мы должны предоставить собственный класс LocalDateAdapter .

Внутри пакета ch.makery.address.util создайте новый класс LocalDateAdapter и скопируйте туда следующий код:

LocalDateAdapter.java

Потом откройте класс Person.java и аннотируйте метод getBirthday() :

Теперь запустите приложение ещё раз. Попытайтесь сохранить и загрузить xml-файл с данными. Приложение должно автоматически загружать последний открытый файл после перезапуска.

Читайте также: