Использование режима EXPLICIT с FOR XML
Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure
Как описано в статье, создание XML с помощью РЕЖИМА FOR XML, RAW и AUTO не обеспечивает много контроля над формой XML, созданной из результата запроса. Однако режим EXPLICIT предоставляет наибольшую гибкость при формировании желаемого XML из результатов запроса.
Запрос в режиме EXPLICIT должен быть написан особым способом, при котором в запросе явно задаются дополнительные сведения о требуемом XML, такие как ожидаемый уровень вложенности в XML. В зависимости от запрашиваемого XML написание запросов режима EXPLICIT может оказаться весьма трудоемким. Может оказаться, что использование режима PATH с вложениями является более простой альтернативой написанию запросов в режиме EXPLICIT.
Поскольку требуемый XML описывается в режиме EXPLICIT в самом запросе, следует убедиться в том, что порождаемый XML имеет необходимую форму и является корректным.
Обработка набора строк в режиме EXPLICIT
Режим EXPLICIT преобразует набор строк, получаемый в результате выполнения запроса, в XML-документ. Для того чтобы режим EXPLICIT создал XML-документ, набор строк должен иметь определенный формат. То есть необходимо написать запрос SELECT для создания набора строк, универсальной таблицы, имеющей определенный формат, так чтобы логика обработки могла создать желаемый XML.
Во-первых, запрос должен создавать следующие два столбца метаданных:
первый столбец должен предоставлять номер тега текущего элемента (целочисленного типа), с именем столбца Tag. В запросе должен быть указан уникальный номер тега для каждого элемента, который будет создан из набора строк;
второй столбец должен задавать номер тега для родительского элемента, и этот столбец должен иметь имя Parent. Таким образом, столбцы Tag и Parent предоставляют сведения об иерархии.
Значения этих столбцов метаданных вместе со сведениями в именах столбцов используются для создания желаемого XML. Запрос должен предоставлять имена столбцов определенным образом. Также обратите внимание на то, что значение 0 или NULL в столбце Parent указывает на то, что у соответствующего элемента нет родителя. Такой элемент добавляется в XML в качестве элемента верхнего уровня.
Для понимания того, как универсальная таблица, сформированная запросом, преобразуется в результат XML, предположим, что написан запрос, который создает универсальную таблицу.
Обратите внимание на следующие особенности этой универсальной таблицы:
Первые два столбца Tag и Parent являются метастолбцами. Эти значения определяют иерархию.
Имена столбцов указываются определенным образом, как описано далее в этой статье.
При формировании XML из этой универсальной таблицы данные таблицы секционируются вертикально на группы столбцов. Группировка определяется на основании значения Tag и имен столбцов. При конструировании XML логика обработки выбирает одну группу столбцов для каждой строки и создает элемент. В данном примере происходит следующее:
для значения столбца Tag , равного 1 в первой строке, столбцы, имена которых включают тот же номер тега, Customer!1!cid и Customer!1!name, образуют группу. Эти столбцы используются для обработки строки, и, возможно, вы заметили, что форма созданного элемента
<Customer id=... name=...>
. Формат имени столбца описан далее в этой статье.Для строк со значением столбца тега 2 столбца Order!2!id и Order!2!date формирует группу, которая затем используется в конструкторе элементов.
<Order id=... date=... />
для строк со значением столбца Tag , равным 3, столбцы OrderDetail!3!id!id и OrderDetail!3!pid!idref образуют группу. Каждая из этих строк создает элемент из
<OrderDetail id=... pid=...>
этих столбцов.
При создании XML-иерархии строки обрабатываются по порядку. Иерархия XML определяется так, как показано далее.
Первая строка задает значение Tag , равное 1, и значение Parent , равное NULL. Поэтому соответствующий элемент,
<Customer>
элемент, добавляется как элемент верхнего уровня в XML.<Customer cid="C1" name="Janine">
Вторая строка задает значение Tag , равное 2, и значение Parent , равное 1. Поэтому элемент,
<Order>
элемент, добавляется в качестве дочернего<Customer>
элемента элемента.<Customer cid="C1" name="Janine"> <Order id="O1" date="1/20/1996">
Следующие две строки задают значение Tag , равное 3, и значение Parent , равное 2. Поэтому два элемента,
<OrderDetail>
элементы, добавляются в качестве дочерних<Order>
элементов элемента.<Customer cid="C1" name="Janine"> <Order id="O1" date="1/20/1996"> <OrderDetail id="OD1" pid="P1"/> <OrderDetail id="OD2" pid="P2"/>
Последняя строка задает 2 в качестве номера Tag и 1 в качестве номера тэга Parent . Поэтому в родительский элемент добавляется еще один
<Order>
дочерний<Customer>
элемент.<Customer cid="C1" name="Janine"> <Order id="O1" date="1/20/1996"> <OrderDetail id="OD1" pid="P1"/> <OrderDetail id="OD2" pid="P2"/> </Order> <Order id="O2" date="3/29/1997"> </Customer>
В итоге, значения в метастолбцах Tag и Parent , сведения, указанные в именах столбцов, и правильный порядок строк создают желаемый XML при использовании режима EXPLICIT.
Упорядочение строк универсальной таблицы
При конструировании XML строки в универсальной таблице обрабатываются по порядку. Поэтому для получения правильных экземпляров потомков, ассоциированных с их родителями строки в наборе строк должны быть упорядочены так, чтобы за каждым родительским узлом следовали его потомки.
Указание имен столбцов в универсальной таблице
При написании запросов в режиме EXPLICIT имена столбцов в результирующем наборе строк должны быть заданы с использованием описанного далее формата. Они предоставляют сведения о преобразовании, включая имена элементов и атрибутов и другие дополнительные сведения, задаваемые при помощи директив.
Общий формат имеет вид:
ElementName!TagNumber!AttributeName!Directive
Далее следует описание частей формата.
ElementName
Результирующий универсальный идентификатор элемента. Например, если Customers задано в качестве ElementName, формируется элемент
<Customers>
.TagNumber
Уникальное значение тега, назначенное элементу. Это значение с помощью двух метастолбцов, Tag и Parent, определяет вложенность элементов в результирующем XML.
AttributeName
Предоставляет имя создаваемого атрибута для указанного элемента ElementName. Это поведение, если директива не указана.
Если задано значение Directive , имеющее тип xml, cdataили element, оно используется для создания дочернего элемента ElementName, к которому добавляется значение столбца.
При указании значения Directiveзначение AttributeName может быть пустым. Например: ElementName!TagNumber!!Directive. В этом случае значение столбца напрямую содержится в ElementName.
Directive
ЗначениеDirective является необязательным и может использоваться с целью предоставления дополнительных сведений для создания XML. ЗначениеDirective служит двум целям.
Одной из целей является кодирование значений в виде ID, IDREF и IDREFS. Можно указать ключевые слова ID, IDREFи IDREFS в качестве значений Directive. Эти директивы переопределяют типы атрибутов. Это позволяет создавать связи внутри документа.
Также можно использовать значение Directive для указания того, как сопоставлять строковые данные с XML. Ключевые слова hide, element, elementxsinil, xml, xmltextи cdata также могут быть использованы в качестве значения Directive. Директива hide скрывает узел. Это полезно при извлечении значений только в целях сортировки, но они не нужны в результирующем XML.
Директива element формирует содержащийся элемент вместо атрибута. Содержащиеся данные кодируются как сущность. Например, символ < превращается в <. Для значений столбцов, равных NULL, элемент не формируется. Если требуется, чтобы для столбцов со значениями NULL формировался элемент, можно указать директиву elementxsinil . При этом будет сформирован элемент с атрибутом xsi:nil=TRUE.
Директива xml аналогична директиве element , однако при ее использовании не происходит кодирования сущности. Директива элемента может сочетаться с ID, IDREF или IDREFS, а директива XML не допускается с какой-либо другой директивой, кроме скрытия.
Директива cdata содержит данные путем упаковывания их с помощью раздела CDATA. Содержимое не закодировано. Первоначальный тип данных должен быть текстовым, например varchar, nvarchar, textили ntext. Эта директива может использоваться только совместно с hide. При использовании этой директивы не следует задавать значение AttributeName .
Объединение директив между этими двумя группами допускается в большинстве случаев, но объединение их между собой не допускается.
Если директива и AttributeName не указаны, например Customer!1, то подразумевается директива элемента, например Customer!1!! элемент и данные столбца содержатся в элементе ElementName.
Если задана директива xmltext , содержимое столбца упаковывается в один тэг, который интегрируется с оставшейся частью документа. Эта директива полезна при выборке перегруженных, неиспользуемых XML-данных, сохраненных в столбец при помощи OPENXML. Дополнительные сведения см. в разделе OPENXML (SQL Server).
Если задано значение AttributeName , имя тега заменяется указанным именем. В противном случае атрибут добавляется к текущему списку атрибутов включаемых элементов путем помещения содержимого в начало содержимого без кодирования сущности. Столбец с этой директивой должен быть текстового типа, например varchar, nvarchar, char, nchar, textили ntext. Эта директива может использоваться только совместно с hide. Эта директива полезна при выборке перегруженных данных, хранящихся в столбце. Если содержимое не является хорошо сформированным XML, поведение не определено.
Следующие шаги
В следующем примере демонстрируется применение режима EXPLICIT.
- Пример. Получение сведений о сотрудниках
- Пример. Указание директивы ELEMENT
- Пример. Задание директивы ELEMENTXSINIL
- Пример: конструирование одноуровневых элементов в режиме EXPLICIT
- Пример. Указание директив ID и IDREF
- Пример. Указание директив ID и IDREFS
- Примеры. Указание директивы HIDE
- Пример. Указание директивы ELEMENT и кодировка сущности
- Пример. Задание директивы CDATA
- Пример. Указание директивы XMLTEXT