Как читать и записывать XML-файлы с помощью кода
Программирование

Как читать и записывать XML-файлы с помощью кода

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

Вы хотите узнать, как читать и записывать XML-файл из java?

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

Java Standard Edition (SE) включает Java API for XML Processing (JAXP) , который является зонтичным термином, охватывающим большинство аспектов обработки XML. К ним относятся:

  • DOM: Объектная модель документа включает классы для работы с артефактами XML, такими как элемент, узел, атрибуты и т.д.API DOM загружает полный XML-документ в память для обработки, поэтому он не очень подходит для работы с большими XML-файлами.
  • SAX: Простой API для XML – это алгоритм чтения XML, управляемый событиями. Здесь XML обрабатывается путем обстрела событий, обнаруженных при чтении XML. Использование этого метода требует мало памяти, но работа с API сложнее, чем работа с DOM.
  • StAX: Потоковый API для XML является недавним дополнением к API XML и обеспечивает высокопроизводительную потоковую фильтрацию, обработку и модификацию XML. Хотя он позволяет избежать загрузки всего XML-документа в память, он обеспечивает архитектуру типа pull, а не архитектуру, управляемую событиями, поэтому приложение проще в кодировании и понимании, чем при использовании SAX API.

В этой статье мы используем DOM API , чтобы продемонстрировать, как читать и записывать XML-файлы из java. Два других API мы рассмотрим в следующих статьях

Образец XML-файла

Для целей этой статьи мы продемонстрируем концепции, используя следующий образец XML, который можно найти здесь:

<?xml version='1. 0'?>
<catalog>
<bookid'bk101'>
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44. 95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<bookid'bk102'>
<author>Ralls, Kim</author>

Чтение файла XML

Давайте рассмотрим основные шаги, необходимые для чтения XML-файла с помощью DOM API

Первым шагом будет получение экземпляра DocumentBuilder. Этот конструктор используется для разбора XML-документов. Для базового использования мы делаем это следующим образом:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
DocumentBuilder builder = factory.newDocumentBuilder();

Теперь мы можем загрузить весь документ в память, начиная с корневого элемента XML. В нашем примере это элемент catalog

File file =.;// XML file to read
Document document = builder.parse(file);
Element catalog = document.getDocumentElement();

Вот и все, друзья! API DOM для чтения XML действительно прост. Теперь у вас есть доступ ко всему XML-документу, начиная с его корневого элемента, каталога. Давайте теперь посмотрим, как с ним работать

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

Теперь, когда у нас есть корневой элемент XML, мы можем использовать DOM API для извлечения интересных самородков информации

Получите все дочерние элементы корневого элемента в виде книг и пройдитесь по ним. Обратите внимание, что getChildNodes() возвращает все дочерние элементы, включая текст, комментарии и т.д. Для нашей цели нам нужны только дочерние элементы, поэтому мы пропустим остальные

NodeList books = catalog.getChildNodes();
forinti =, ii =, n = books.getLength() ; i < n ; i++) {
Node child = books.item(i);
if( child.getNodeType() != Node.ELEMENT_NODE )
  continue
Element book = (Element)child;
// work with the book Element here

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

staticprivateNodefindFirstNamedElement(Node parent,String tagName)

NodeList children = parent.getChildNodes();
forinti =, in = children.getLength() ; i < in ; i++) {
  Node child = children.item(i);
  if( child.getNodeType() != Node.ELEMENT_NODE )
  continue
  if( child.getNodeName().equals(tagName) )
  returnchild;

returnnull

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

staticprivateStringgetCharacterData(Node parent)

StringBuilder text =newStringBuilder();
if( parent ==null
  returntext.toString();
NodeList children = parent.getChildNodes();
forintk =, kn = children.getLength() ; k < kn ; k++) {
  Node child = children.item(k);
  if( child.getNodeType() != Node.TEXT_NODE )
  break
  text.append(child.getNodeValue());

returntext.toString();

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

NodeList books = catalog.getChildNodes();
forinti =, ii =, n = books.getLength() ; i < n ; i++) {
Node child = books.item(i);
if( child.getNodeType() != Node.ELEMENT_NODE )
  continue
Element book = (Element)child;
ii++;

String id = book.getAttribute('id');
String author = getCharacterData(findFirstNamedElement(child,'author'));
String title = getCharacterData(findFirstNamedElement(child,'title'));
String genre = getCharacterData(findFirstNamedElement(child,'genre'));
String price = getCharacterData(findFirstNamedElement(child,'price'));
String pubdate = getCharacterData(findFirstNamedElement(child,'pubdate'));
String descr = getCharacterData(findFirstNamedElement(child,'description'));

System.out.printf('%3d. book id = %s
'
' author: %s
'
' title: %s
'
' genre: %s
'
' price: %s
'
' pubdate: %s
'
' descr: %s
'
ii, id, author, title, genre, price, pubdate, descr);

Запись выходных данных XML

Java предоставляет XML Tranform API для преобразования данных XML. Мы используем этот API вместе с преобразованием идентичности для создания выходных данных

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

id=bk113
author=Jane Austen
title=Pride and Prejudice
genre=Romance
price=6. 99
publish_date=2010-04-01
description='It is a truth universally acknowledged, that a single man in possession of a good fortune must be in want of a wife.'So begins Pride and Prejudice, Jane Austen's witty comedy of manners-one of the most popular novels of all time-that features splendidly civilized sparring between the proud Mr. Darcy and the prejudiced Elizabeth Bennet as they play out their spirited courtship in a series of eighteenth-century drawing-room intrigues.

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

File file =.;// XML file to read
Document document = builder.parse(file);
Element catalog = document.getDocumentElement();

Мы загружаем данные из файла свойств, используя класс Properties, поставляемый с java. Код довольно прост и показан ниже

String propsFile =.;
Properties props =newProperties();
try(FileReader in =newFileReader(propsFile)) {
props.load(in);

После загрузки свойств мы извлекаем значения, которые хотим добавить, из файла свойств

String id = props.getProperty('id');
String author = props.getProperty('author');
String title = props.getProperty('title');
String genre = props.getProperty('genre');
String price = props.getProperty('price');
String publish_date = props.getProperty('publish_date');
String descr = props.getProperty('description');

Теперь создадим пустой элемент book

Element book = document.createElement('book');
book.setAttribute('id', id);

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

List<String> elnames =Arrays.asList('author''title''genre''price'
'publish_date''description');
for(String elname : elnames) {
Element el = document.createElement(elname);
Text text = document.createTextNode(props.getProperty(elname));
el.appendChild(text);
book.appendChild(el);

catalog.appendChild(book);

Вот как это делается. В элемент catalog теперь добавлен новый элемент book. Осталось только записать обновленный XML

Для записи XML нам нужен экземпляр Transformer, который создается, как показано ниже. Обратите внимание, что мы запрашиваем отступы выходного XML с помощью метода setOutputProperty()

TransformerFactory tfact = TransformerFactory.newInstance();
Transformer tform = tfact.newTransformer();
tform.setOutputProperty(OutputKeys.INDENT,'yes');
tform.setOutputProperty('{http://xml.apache.org/xslt}indent-amount''3');

Последним шагом в генерации выходных данных XML является применение транформации. Результат появляется в выходном потоке System.out

tform.transform(newDOMSource(document),newStreamResult(System.out));

Чтобы записать вывод непосредственно в файл, используйте следующее

tform.transform(newDOMSource(document),newStreamResult(newFile('output.xml')));

На этом мы завершаем статью о чтении и записи XML-файлов с помощью DOM API

Использовали ли вы DOM API в своих приложениях? Как он показал себя? Пожалуйста, дайте нам знать в комментариях ниже

Теги

Об авторе

Алексей Белоусов

Привет, меня зовут Филипп. Я фрилансер энтузиаст . В свободное время занимаюсь переводом статей и пишу о потребительских технологиях для широкого круга изданий , не переставая питать большую страсть ко всему мобильному =)

Комментировать

Оставить комментарий