Программирование

Как читать и писать файлы XML с кодом

Как читать и писать файлы XML с кодом

Хотите узнать, как читать и писать XML-файл из Java?

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

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

  • DOM: объектная модель документа включает в себя классы для работы с артефактами XML, такими как элемент, узел, атрибуты и т. Д. API DOM загружает полный документ XML в память для обработки, поэтому он не очень подходит для работы с большими файлами XML.
  • SAX: Simple API for XML — это управляемый событиями алгоритм чтения XML. Здесь XML обрабатывается путем запуска событий, найденных при чтении XML. Требования к памяти для использования этого метода низкие, но работа с API более сложна, чем работа с DOM.
  • StAX: Streaming API для XML является недавним дополнением к XML APIs и обеспечивает высокопроизводительную потоковую фильтрацию, обработку и модификацию XML. Несмотря на то, что он избегает загрузки всего XML-документа в память, он предоставляет архитектуру типа pull, а не архитектуру, управляемую событиями, поэтому приложение легче кодировать и понимать, чем с помощью SAX API.

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

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

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

<?xml version="1.0"?> <catalog> <book id="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> <book id="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. В нашем примере это элемент каталога .

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

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

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

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

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

 NodeList books = catalog.getChildNodes(); for (int i = 0, ii = 0, 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. Как вы можете видеть, процедура включает в себя получение списка дочерних узлов и их циклический отбор, выбирая узлы элементов с указанным именем.

 static private Node findFirstNamedElement(Node parent,String tagName) { NodeList children = parent.getChildNodes(); for (int i = 0, in = children.getLength() ; i < in ; i++) { Node child = children.item(i); if ( child.getNodeType() != Node.ELEMENT_NODE ) continue; if ( child.getNodeName().equals(tagName) ) return child; } return null; } 

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

 static private String getCharacterData(Node parent) { StringBuilder text = new StringBuilder(); if ( parent == null ) return text.toString(); NodeList children = parent.getChildNodes(); for (int k = 0, kn = children.getLength() ; k < kn ; k++) { Node child = children.item(k); if ( child.getNodeType() != Node.TEXT_NODE ) break; text.append(child.getNodeValue()); } return text.toString(); } 

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

 NodeList books = catalog.getChildNodes(); for (int i = 0, ii = 0, 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\n" + " author: %s\n" + " title: %s\n" + " genre: %s\n" + " price: %s\n" + " pubdate: %s\n" + " descr: %s\n", ii, id, author, title, genre, price, pubdate, descr); } 

Написание XML-вывода

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

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

 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 = new Properties(); try (FileReader in = new FileReader(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"); 

Давайте теперь создадим пустой элемент книги .

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

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

 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); 

И вот как это делается. К элементу каталога теперь добавлен новый элемент книги . Все, что остается сейчас, это выписать обновленный 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(new DOMSource(document), new StreamResult(System.out)); 

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

 tform.transform(new DOMSource(document), new StreamResult(new File("output.xml"))); 

И это завершает эту статью о чтении и записи файлов XML с использованием DOM API.

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

Похожие посты
Программирование

Что такое канал RSS? (И где его взять)

Программирование

7 причин, почему изображения не загружаются на ваш сайт

Программирование

Запустите агент SQL Server: настройте SQL Server 2012

Программирование

15 лучших бесплатных обоев дня Святого Патрика