Oracle xml добавить узел

Обновлено: 03.07.2024

В предыдущей публикации были рассмотрены некоторые приёмы манипуляции с XML в Oracle, теперь рассмотрим как делать выборку данных напрямую в XML. Это на мой взгляд самая интересная часть.

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

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

Создадим таблицу с городами:


И создадим таблицу с улицами:


Заполним наши таблицы демонстрационными данными:


Теперь всё готово, приступаем.

1. XMLElement — Выбор XML узла

В самом простом виде выборка в виде XML выглядит так:


Теперь проделаем то же самое с нашей таблицей CITY — выберем все города.


В результате мы получили набор элементов, теперь научимся объединять все эти элементы в один родительский узел, это проще простого.

2. XMLAGG — Объединение (группировка) элементов в родительский узел.

Объединим все наши города из предыдущего примера в один родительский узел country.


Как видим, в результате, мы получили элемент country с вложенным набором элементов city.

Теперь добавим название страны, и узнаем как добавлять атрибуты.

3. XMLATTRIBUTES — Добавление атрибутов в XML элемент.

Начнем с простого, добавим название страны.
Для этого надо просто после названия узла, добавить ещё один параметр XMLATTRIBUTES с перечисленными в скобках параметрами атрибутов.


Вот и всё что нам понадобится для выборки данных в виде XML, теперь попробуем сделать что нибудь более сложное.

Во первых, вынесем наименование города в атрибут, и добавим идентификатор города.


В результате получим XML вида:


Теперь добавим городам дочерние элементы street (улицы).
Для этого нам придётся использовать группировку.
Присоединим таблицу street и сгруппируем по идентификатору и наименованию города.


В результате получим XML вида:


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

DOM Узлы

Согласно DOM любая часть XML документа является узлом.

В соответствии с DOM:

Пример DOM

Взгляните на соедующий XML файл (books.xml):

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="КУЛИНАРИЯ">
<title lang="ru">Самогон и другие спиртные напитки домашнего приготовления</title>
<author>Байдакова Ирина</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="ДЛЯ ДЕТЕЙ">
<title lang="ru">Арлекино и Пьеро</title>
<author>Аарх Андрей</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="ВЕБ">
<title lang="ru">Ajax в действии</title>
<author>Д. Крейн</author>
<author>Э. Паскарелло</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="ВЕБ" cover="мягкая обложка">
<title lang="ru">Библия JavaScript 4-е Издание</title>
<author>Дэнни Гудман</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>

Корневой узел в XML выше называется <bookstore>. Все другие узлы в документе содержатся внутри <bookstore>.

Корневой узел <bookstore> содержит четыре узла <book>.

Первый узел <book> содержит четыре узла: <title>, <author>, <year> и <price>, каждый из которых содержит по одному текстовому узлу "Самогон и другие спиртные напитки домашнего приготовления", "Байдакова Ирина", "2005" и "30.00" соответственно.

Текст Всегда Хранится в Текстовых Узлах

Распространенной ошибкой при обработке DOM является ожидание того, что узел элемента содержит текст.

Однако, текст узла элемента хранится в текстовом узле.

В этом примере: <year>2005</year>, узел элемента <year>, содержит текстовый узел со значением "2005".

XMLElement takes an element name for identifier , an optional collection of attributes for the element, and arguments that make up the content of the element. It returns an instance of type XMLType . XMLElement is similar to SYS_XMLGen except that XMLElement can include attributes in the XML returned, but it does not accept formatting using the XMLFormat object.

The XMLElement function is typically nested to produce an XML document with a nested structure, as in the example in the following section.

You must specify a value for identifier , which Oracle Database uses as the enclosing tag. The identifier can be up to 4000 characters and does not have to be a column name or column reference. It cannot be an expression or null.

The objects that make up the element content follow the XMLATTRIBUTES keyword. In the XML_attributes_clause , if the value_expr is null, then no attribute is created for that value expression. The type of value_expr cannot be an object type or collection. If you specify an alias for value_expr using the AS clause, the c_alias can be up to 4000 characters.

For the optional value_expr that follows the XML_attributes_clause in the diagram:

If value_expr is a scalar expression, then you can omit the AS clause, and Oracle uses the column name as the element name.

If value_expr is an object type or collection, then the AS clause is mandatory, and Oracle uses the specified c_alias as the enclosing tag.

If value_expr is null, then no element is created for that value expression.

The following example produces an Emp element for a series of employees, with nested elements that provide the employee's name and hire date:

The following similar example uses the XMLElement function with the XML_attributes_clause to create nested XML elements with attribute values for the top-level element:

Notice that the AS identifier clause was not specified for the last_name column. As a result, the XML returned uses the column name last_name as the default.

Finally, the next example uses a subquery within the XML_attributes_clause to retrieve information from another table into the attributes of an element:

Метод appendChild() добавляет дочерний узел к существующему узлу.

Новый узел добавляется (присоединяется) после всех уже существующих дочерних узлов.

Примечание: Если местоположение узла имеет значение, то следует использовать метод insertBefore().

Следующий фрагмент кода создает элемент <edition> и добавляет его после последнего дочернего элемента первого элемента <book>:

  1. Предположим, что файл books.xml был загружен в переменную xmlDoc
  2. Создаем новый узел <edition>
  3. Добавляем этот узел в первый элемент <book>

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

  1. Предположим, что файл books.xml был загружен в переменную xmlDoc
  2. Создаем новый узел <edition>
  3. Создаем новый текстовый узел "first"
  4. Добавляем текстовый узел к узлу <edition>
  5. Добавляем узел <edition> в элемент <book>

Вставка узла - insertBefore()

Метод insertBefore() вставляет узел перед указанным дочерним узлом.

Этот метод полезен, когда важно местоположение добавляемого узла:

  1. Предположим, что файл books.xml был загружен в переменную xmlDoc
  2. Создаем новый узел элемента <book>
  3. Вставляем новый узел перед последним элементом <book>

Если второй параметр метода insertBefore() равен null, то новый узел будет добавлен после последнего существующего дочернего узла.

x.insertBefore(newNode, null) и x.appendChild(newNode) оба добавят новый дочерний узел к узлу "x".

Добавление нового атрибута

Метод setAttribute() устанавливает значение атрибута.

  1. Предположим, что файл books.xml был загружен в переменную xmlDoc
  2. Устанавливаем атрибуту "edition" значение "first" в первом элементе <book>.

Примечание: Не существует метода с названием addAttribute(). Метод setAttribute() создаст новый атрибут, если атрибут не существует. Если атрибут уже существует, метод setAttribute() перезапишет существующее значение.

Добавление текста в текстовый узел - insertData()

Метод insertData() вставляет данные в существующий текстовый узел.

Метод insertData() принимает два параметра:

  • offset – Позиция, куда будет вставлена строка (начинается с 0)
  • string – Вставляемая строка

Следующий фрагмент кода добавит строку "Easy " в текстовый узел первого элемента <title> загруженного XML документа:

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