Как вставить комментарий в XML документ?
Ниже код моей функции. Возможно, моя проблема заключается в том, что я неправильно понял как работает insertBefore. Работу этого метода я понял так, insertBefore имеет два параметра: первый параметр — узел, который хотим вставить, второй параметр — перед каким узлом хотим вставить. Вызываем сам метод insertBefore у того узла, для которого нововставленный узел будет дочерним. Если все так, тогда не могу понять, почему данный код не вставляет комментарий там, где нужно.
public static Document addCommentsToDocument(Object obj, String tagName, String comment) throws Exception < String fileName = new String("/home/albuquerque/XML.xml"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(file); document.getDocumentElement().normalize(); Node root = document.getDocumentElement(); NodeList listNode = root.getChildNodes(); Comment com = document.createComment(comment); for (int i = 0; i < listNode.getLength(); i++) < Node node = listNode.item(i); root.insertBefore(com, node); >return document; >
Ниже код XML. Перед каждым тегом, кроме родительского нужно вставить комментарий.
a b string1 string2
Но вставка происходит такая:
1 1 string1 string2
Что не так я делаю?
Отслеживать
Maksim Ohotnikov
задан 16 окт 2018 в 21:34
Maksim Ohotnikov Maksim Ohotnikov
258 3 3 серебряных знака 20 20 бронзовых знаков
Как я понимаю, вы одну и ту же ноду-коммент вставляете. В итоге она оказывается в конце. Нужно в цикле создавать новые узлы-комментарии и их вставлять.
16 окт 2018 в 23:19
@Alexander, вчера еще исправил это, но не понял как. Все верно, вот как я исправил это n.getParentNode().insertBefore(document.createComment(comment), n); Я просто узел вставлял перед каждым елементом xml и следующей итерацией передвигал в итоге он в конце оказался у последнего, так?
XML – Комментарии
В этой главе объясняется, как работают комментарии в документах XML. Комментарии XML похожи на комментарии HTML. Комментарии добавляются в виде примечаний или строк для понимания цели XML-кода.
Комментарии могут быть использованы для включения связанных ссылок, информации и терминов. Они видны только в исходном коде; не в коде XML. Комментарии могут появляться в любом месте XML-кода.
Синтаксис
XML-комментарий имеет следующий синтаксис –
Комментарий начинается с и заканчивается -> . Вы можете добавить текстовые заметки в качестве комментариев между персонажами. Вы не должны вкладывать один комментарий в другой.
пример
Следующий пример демонстрирует использование комментариев в документе XML –
Tanmay A
Любой текст между символами и -> считается комментарием.
Правила XML-комментариев
Следующие правила должны соблюдаться для XML-комментариев –
Универсальный загрузчик XML на java. Или как загрузить файлы ГАР на 250 гб и остаться при памяти
С проблемой загрузки больших XML столкнулся при переходе с КЛАДР и ФИАС на справочники ГАР — Государственный адресный реестр (Федеральная информационная адресная система).
Справочник ГАР содержит более подробную информацию чем предыдущие классификаторы. В том числе информацию по муниципальным делениям. В связи с чем справочник после распаковки занимет около 250 ГБ, что примерно в 3 раза больше чем тот же ФИАС.
Предыдущая загрузка работала на DOM-модели, т. е. весь XML-файл считывался в память. Соответственно при попытке загрузить ГАР таким же способом стали стабильно получать OutOfMemory. А значит настало время менять подход к загрузке)
DOM (Document Object Model) — это стандартный интерфейс для работы с документами в формате XML (Extensible Markup Language). DOM-модель представляет XML-документ в виде дерева объектов, где каждый элемент и атрибут документа является узлом дерева.
SAX (Simple API for XML) является событийно-ориентированным API для чтения XML-документа. Он предоставляет возможность читать XML-документ последовательно и обрабатывать события, такие как начало и конец элемента, содержимое элемента и т. д.
StAX (Streaming API for XML) также является API для последовательного чтения и записи XML-документов. Он предоставляет потоковый доступ к XML-документу, позволяя читать его и записывать по частям. StAX предоставляет возможность читать и записывать XML-документы в виде потока событий, аналогично SAX, но также предоставляет возможность читать и записывать XML-документы в виде итерируемых наборов событий. StAX позволяет эффективно обрабатывать большие XML-документы и не требует реализации обработчиков событий.
Загрузка XML-документа с помощью DOM-модели довольно медленная, особенно для больших документов, поскольку требует создания полной структуры DOM в памяти. Однако, DOM-модель позволяет легко и удобно работать с XML-документами, поэтому она широко используется в Java-приложениях.
SAX и StAX позволяет обрабатывать XML-документы любого размера, поскольку он не хранит всю структуру в памяти. Однако, для работы необходимо реализовать обработчики событий.
Одним из главных преимуществ использования StAX является его скорость работы и эффективность. И и отличие от DOM, который загружает весь XML-документ в память перед его обработкой, StAX-парсер обрабатывает XML-документ по одному элементу за раз, что позволяет работать с большими XML-файлами.
Понятно. Останавливаемся на StAX: )
Реализуем класс для универсальной загрузки XML. Будем читать данные комфортными порциями и мапить их на произвольные объекты. Класс объекта передаем в загрузчик.
Структура справочника состоит из нескольких типов XML-файлов. Для каждой создадим таблицу в БД, опишим сущности. Пример для адресных объектов:
Читаем нашим XML загрузчиком адреса пачками в структуру GarAddressobject и тут же производим сохранение в БД.
Для файлов домов, муниципальных образований и пр. алгоритм такой же, полный код загрузчика по ссылке
— Регламентная загрузка ГАР перестала падать изза нехватки памяти
— Можно управлять кол-вом строк, которые за раз вычитывает XML-загрузчик
— Сам загрузчик довольно универсальный, его можно переиспользовать в других задачах
— Понимаем отличия в подходах DOM и SAX. Знаем где какой вариант лучше подойдет: )
Всем спасибо! Комментарии приветствуются)
Использование аннотаций с JAXB, генерация XML schema из java-кода
Однажды, возникла необходимость настройки формата дат внутри XML документов. Работа с документами осуществлялась с помощью JAXB. Всвязи с этим коллеги нашли в интернете замечательную публикацию на сайте http://ooxs-be.goracer.nl/EN/java/Java%20and%20XML%20Binding.html

Ниже перевод не совсем близкий к тексту. Я слегка видоизменяю его для улучшения понимаемости. (По крайней мере мне хочется её улучшить). Если что-то не совсем понятно, смотрите оригинал.
Introduction
При работе с XML в Java, он может рассматриваться просто как текст, который должен быть прочитан изменен и куда-то записан. Т.о. это может быть сделано обычной конкатенацией строк или с помощью DOM-модели в памяти для доступа, создания или модификации документа.
В большинстве случаев, однако, кроме XML документа имеется набор классов — модель в виде beans или POJO, не важно как классы представлены и называются, но эти классы должны преобразовываться в XML документ и обратно из XML документа превращаться в набор классов. Это нужно для посылки этих классов в запросе на веб-сервис, для сохранения в файле и т.п.
Такая взаимосвязь модели Java объектов и XML представления документов называется англоговорящими программистами binding. Создание объектов из XML называется unmarshalling, а обратная операция генерации XML из Java объектов — marshalling.

Есть различные способы для реализации unmarshalling-а и marshalling-a:
- Написать SAX парсер для создания Java объектов
- Работать с DOM деревом для извлечения нужных объектов из него
- Использовать специальный API такой как JAXB, Apache Commons Betwixt, и т.д.
package be.ooxs.example.jaxb; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlType(propOrder = < "name", "members" >, name = "group") @XmlRootElement public class Group < private String name; private Listmembers = new ArrayList(); public String getName() < return name; >public void setName(String name) < this.name = name; >public List getMembers() < return members; >public void setMembers(List members) < this.members = members; >>
Подобным образом добавляем аннотации в дочерний класс
package be.ooxs.example.jaxb; import java.util.Date; import javax.xml.bind.annotation.XmlType; @XmlType(propOrder = < "lastName", "firstName", "birthDate" >, name = "person") public class Person < private Date birthDate; private String firstName; private String lastName; public Date getBirthDate() < return birthDate; >public void setBirthDate(Date birthDate) < this.birthDate = birthDate; >public String getFirstName() < return firstName; >public void setFirstName(String firstName) < this.firstName = firstName; >public String getLastName() < return lastName; >public void setLastName(String lastName) < this.lastName = lastName; >>
И, наконец, ниже класс Application выполняющий сериализацию (marshalling-unmarshalling) вышеприведенных классов с помощью JAXB:
package be.ooxs.example.jaxb; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class Application < private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); public Group createJavaObjectExample1() < Group group = new Group(); group.setName("Test Group 1"); try < group.getMembers().add(createPerson("Alice", "Anderssen", "1970-01-01")); group.getMembers().add(createPerson("Bert", "Bobo", "1980-02-02")); >catch (ParseException exception) < Logger.getLogger(Application.class.getName()). log(Level.ALL, "createJavaObjectExample1 threw ParseException", exception); >return group; > public Person createPerson(String firstName, String lastName, String birthDate) throws ParseException < Person person = new Person(); person.setBirthDate(format.parse(birthDate)); person.setFirstName(firstName); person.setLastName(lastName); return person; >public void marshallExample() < //. >public void unmarshallExample() < //. >public static void main(String[] args) < Application instance = new Application(); instance.marshallExample(); instance.unmarshallExample(); System.out.println("Done"); >>
Добавим код для генерации XML, и выполним приложение добавив в группу пару элементов для демонстрации JAXB API:
public void marshallExample() < try < JAXBContext context = JAXBContext.newInstance(Group.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.marshal(createJavaObjectExample1(), System.out); >catch (JAXBException exception) < Logger.getLogger(Application.class.getName()). log(Level.SEVERE, "marshallExample threw JAXBException", exception); >>
Благодаря аннотациям, лишь три строчки кода генерируют XML. (4 для лучшего форматирования для улучшения читаемости)
Test Group 1 Anderssen Alice 1970-01-01T00:00:00+01:00 Bobo Bert 1980-02-02T00:00:00+01:00
Однако в выходном XML есть ряд неожиданных элементов.
Каждый элемент Person помещён внутрь тега members вместо тега person. Это мы изменим позже. А пока посмотрим пример обратного преобразования. Сначала мы повторим предыдущий пример, создадим XML, потом запишем его в byte array. Затем сделаем unmarshalling из сгенерированного предварительно XML.
public void unmarshallExample() < try < JAXBContext context = JAXBContext.newInstance(Group.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); //write XML to an array of bytes ByteArrayOutputStream baos = new ByteArrayOutputStream(); marshaller.marshal(createJavaObjectExample1(), baos); //read XML from array of bytes InputStream bais = new ByteArrayInputStream(baos.toByteArray()); Unmarshaller unmarshaller = context.createUnmarshaller(); Object o = unmarshaller.unmarshal(bais); //prove the Group is recreated Group groupCopy = (Group) o; System.out.println("Objects created from XML:"); System.out.println(groupCopy.getName()); for (Person person : groupCopy.getMembers()) < System.out.println(person.getFirstName()); >> catch (JAXBException exception) < Logger.getLogger(Application.class.getName()). log(Level.SEVERE, "marshallExample threw JAXBException", exception); >>
В результате теста дополнительно к XML получаем следующий output:
Objects created from XML: Test Group 1 Alice Bert Done
JAXB утилиты входят в стандартную инсталляцию Java. При установке Java 6 JDK они устанавливаются в каталог $JAVA_HOME/bin.
Например в дистрибутивах Linux подобных Ubuntu, они будут по умолчанию доступны для вызова из командной строки. Генерация XML schema из Java-классов. Чтобы JAXB утилиты стали доступны под Windows, нужно в переменных окружения указать путь к поддиректорию bin в каталоге с JDK. Для генерации XML schema из Java кода с добавленными аннотациями, используется утилита schemagen: Допустим мы находимся в корневом директории исходников. Т.е. в нём у нас подкаталог be/ooxs/example/jaxb/ с исходниками:
Group.java, Person.java, Application.java Тогда находясь в директории с исходниками мы генерируем XML схему такой командой (я тестируюсь под Windows):
> schemagen -d . -cp . be/ooxs/example/jaxb/Group.java
- -d . задает, что схема будет положена в текущий директорий
- -cp . — classpath. Корневой директорий наших исходников. Т.к. мы в нём и находимся. То указываем точку.
- третий параметр — путь к .java — файлу с исходным кодом корневого элемента нашего XML документа.
Модифицируем аннотации Для получения слегка улучшенной XML структуры, добавим несколько вещей: Для начала добавим пару аннотаций, первая группирует все дочерние элементы используя дополнительный members элемент, вторая изменяет имя каждого дочернего элемента на person.
@XmlElementWrapper(name = «members») @XmlElement(name = «person») public List getMembers()
В результате при повторении теста получим XML:
Test Group 1 Anderssen Alice 1970-01-01T00:00:00+03:00 Bobo Bert 1980-02-02T00:00:00+03:00