Запросы XML с использованием OPENXML
Ключевое слово OPENXML языка Transact-SQL предоставляет набор строк по XML-документам в памяти, подобный таблице или представлению. OPENXML позволяет получить доступ к XML-данным так, как если бы это был реляционный набор строк. Это делается при помощи представления внутреннего отображения XML-документа в виде набора строк. Записи в наборе строк могут храниться в таблицах базы данных.
OPENXML может использоваться в инструкциях SELECT и SELECT INTO в любых позициях, где в качестве источника могут присутствовать поставщики наборов строк, представления или функция OPENROWSET. Дополнительные сведения о синтаксисе инструкции OPENXML см. в разделе OPENXML (Transact-SQL).
Чтобы писать запросы в отношении XML-документа с использованием OPENXML, необходимо сначала вызвать хранимую процедуру sp_xml_preparedocument. Таким образом производится синтаксический анализ XML-документа и возвращается дескриптор для проанализированного документа, готового к использованию. Проанализированный документ является представлением дерева объектной модели документа (DOM) различных узлов в XML-документе. Дескриптор документа передается OPENXML. Затем инструкция OPENXML выдает представление документа в виде набора строк, основываясь на переданных ей параметрах.
![]() |
---|
Начиная с версии SQL Server 2005, хранимая процедура sp_xml_preparedocument использует обновленную под SQL версию средства синтаксического анализа MSXML, Msxmlsql.dll. Эта версия средства синтаксического анализа MSXML была разработана для поддержки SQL Server и остается обратно совместимой с версией MSXML 2.6. |
Внутреннее представление XML-документа должно быть удалено из памяти посредством вызова системной хранимой процедуры sp_xml_removedocument для освобождения памяти.
На следующей иллюстрации показан этот процесс.
Обратите внимание на то, что для понимания OPENXML необходимо иметь общее представление о запросах XPath и XML. Дополнительные сведения о поддержке XPath в SQL Server см. в разделе Использование запросов XPath в SQLXML 4.0.
![]() |
---|
OpenXML позволяет параметризовать шаблоны XPath столбцов и строк как переменные. Такая параметризация может привести к включению выражений XPath, если разработчик допускает демонстрацию параметризации внешним пользователям (например, если аргументы предоставляются через вызываемую извне хранимую процедуру). Чтобы избежать подобных потенциально опасных ситуаций, рекомендуется никогда не допускать демонстрации аргументов XPath внешним вызывающим программам. |
Параметры OPENXML
К числу аргументов OPENXML относятся:
дескриптор XML-документа (idoc)
выражение XPath для распознавания узлов, которые должны быть сопоставлены со строками (rowpattern)
описание набора строк, который должен быть создан;
сопоставление столбцов набора строк и узлов XML;
Обработка XML-документа (idoc)
Дескриптор документа возвращается хранимой процедурой sp_xml_preparedocument.
Выражение XPath для распознавания узлов, подлежащих обработке (rowpattern)
Выражение XPath, указанное аргументом rowpattern, распознает набор узлов в XML-документе. Каждый узел, распознанный rowpattern, соотносится с отдельной строкой в наборе строк, созданном OPENXML.
Узлами, распознанными выражением XPath, могут быть любые узлы XML в XML-документе. Если rowpattern распознает набор элементов в XML-документе, в наборе строк выделяется по одной строке для каждого распознанного узла элемента. Например, если rowpattern приводит к атрибуту, создается строка для каждого узла атрибута, выбранного rowpattern.
Описание набора строк, который должен быть сформирован
Схема набора строк используется OPENXML для создания результирующего набора строк. Можно использовать нижеследующие параметры при указании схемы набора строк.
Использование формата краевой таблицы
Для указания схемы набора строк следует использовать формат краевой таблицы. Не используйте предложение WITH.
При этом OPENXML возвращает набор строк в формате краевой таблицы. Ее так называют потому, что каждый край проанализированного XML-документа сопоставляется со строкой в наборе строк.
Краевые таблицы представляют внутри отдельной таблицы подробную структуру XML-документа. Структура включает в себя имена элементов и атрибутов, иерархию документа, пространства имен и инструкции по обработке. Формат краевой таблицы позволяет получать дополнительные сведения, не отображаемые в метасвойствах. Дополнительные сведения о метасвойствах см. в разделе «Указание метасвойств» в OPENXML29bfd1c6-3f9a-43c4-924a-53d438e442f4.
Дополнительные сведения, предоставляемые краевой таблицей, позволяют сохранять и запрашивать тип данных элемента и атрибута, тип узла, а также сохранять и запрашивать сведения о структуре XML-документа. С учетом этих дополнительных сведений может стать возможным построение собственной системы управления XML-документами.
Используя краевую таблицу, можно писать хранимые процедуры, которые рассматривают XML-документы как входные данные большого двоичного объекта (BLOB), создают краевую таблицу, а затем извлекают и анализируют документ на более детальном уровне. Этот детальный уровень может включать в себя выявление иерархии документа, имен элементов и атрибутов, пространств имен и инструкций по обработке.
Краевая таблица также может служить форматом хранения для XML-документов, если сопоставление с другими реляционными форматами нелогично, и поле ntext не обеспечивает достаточными структурными данными.
В ситуациях, когда возможно использование средства синтаксического анализа XML для исследования XML-документа, можно вместо этого применить краевую таблицу, чтобы получить те же сведения.
В следующей таблице описывается структура краевой таблицы.
Имя столбца |
Тип данных |
Описание |
---|---|---|
id |
bigint |
Уникальный идентификатор узла документа. Идентификатор корневого элемента имеет значение 0. Отрицательные значения идентификаторов зарезервированы. |
parentid |
bigint |
Идентифицирует родительский узел для данного узла. Родительский узел, определенный этим идентификатором, необязательно является родительским элементом. Однако это зависит от типа узла, родительский узел которого определен этим идентификатором. Например, если узел является текстовым, его родительский узел может быть узлом атрибута. Если узел находится на верхнем уровне XML-документа, то его ParentID имеет значение NULL. |
node type |
int |
Определяет тип узла и является целым числом, соответствующим нумерации типов узла объектной модели XML (DOM). Ниже приведены значения, которые могут быть представлены в этом столбце для указания типа узла. 1 = Узел элемента 2 = Узел атрибута 3 = Узел текста 4 = Узел раздела CDATA 5 = Узел ссылки на сущность 6 = Узел сущности 7 = Узел инструкции по обработке 8 = Узел комментария 9 = Узел документа 10 = Узел типа документа 11 = Узел фрагмента документа 12 = Узел нотации Дополнительные сведения см. в разделе «Свойство nodeType» в пакете Microsoft XML (MSXML) SDK. |
localname |
nvarchar(max) |
Отображает локальное имя элемента или атрибута. Принимает значение NULL, если у объекта DOM нет имени. |
prefix |
nvarchar(max) |
Префикс пространства имен для имени узла. |
namespaceuri |
nvarchar(max) |
URI пространства имен для имени узла. Если этот параметр принимает значение NULL, пространство имен не используется. |
datatype |
nvarchar(max) |
Действительный тип данных строки элемента или атрибута; в ином случае имеет значение NULL. Тип данных выводится на основе встроенного DTD или встроенной схемы. |
prev |
bigint |
Идентификатор XML предыдущего элемента этого же уровня. Принимает значение NULL, если нет прямого предыдущего одноуровневого элемента. |
text |
ntext |
Содержит значение атрибута или содержимое элемента в виде текста. Либо принимает значение NULL, если для записи в краевой таблице не требуется значение. |
Использование предложения WITH для указания существующей таблицы
Можно использовать предложение WITH, чтобы указать имя существующей таблицы. Чтобы сделать это, просто укажите имя существующей таблицы, схема которой может быть использована OPENXML для создания набора строк.
Использование предложения WITH для указания схемы
Можно использовать предложение WITH, чтобы указать полную схему. При указании схемы набора строк указываются имена столбцов, их типы данных и их сопоставление с XML-документом.
Можно указать шаблон столбца, применив аргумент ColPattern в SchemaDeclaration. Указанный шаблон столбца используется для сопоставления столбца набора строк с узлом XML, определенным rowpattern, а также используется для определения типа сопоставления.
Если аргумент ColPattern не указан для столбца, столбец набора строк сопоставляется с узлом XML с тем же именем, основываясь на сопоставлении, указанном посредством аргумента flags. Однако если аргумент ColPattern задан как часть указания схемы в предложении WITH, он переопределяет сопоставление, указанное аргументом flags.
Сопоставление столбцов набора строк и узлов XML
В инструкции OPENXML можно по выбору указать тип сопоставления, например с опорой на атрибут или с опорой на элемент, между столбцами набора строк и узлами XML, определенными посредством rowpattern. Эти данные используются в преобразовании между узлами XML и столбцами набора строк.
Сопоставление может быть указано двумя способами, в том числе и обоими сразу:
Используя аргумент flags
Указание сопоставления посредством аргумента flags предполагает соответствие имен, в котором узлы XML сопоставляются с соответствующими столбцами набора строк, имеющими то же имя.
Используя аргумент ColPattern
ColPattern, выражение XPath, указывается как часть SchemaDeclaration в предложении WITH. Сопоставлением, указанным в ColPattern, перекрывается сопоставление, указанное аргументом flags.
ColPattern может использоваться для указания типа сопоставления, например с опорой на атрибут или элемент, которое перекрывает или расширяет сопоставление по умолчанию, указанное аргументом flags.
ColPattern указывается в следующих ситуациях:
Имя столбца в наборе строк отличается от имени атрибута или элемента, с которым оно сопоставлено. В этом случае ColPattern используется для определения имени элемента или атрибута в формате XML, с которым сопоставлен столбец набора строк.
Необходимо сопоставить атрибут метасвойства со столбцом. В этом случае ColPattern используется для определения метасвойства, с которым сопоставлен столбец набора строк. Дополнительные сведения о том, как использовать метасвойства, см. в разделе Определение метасвойств в инструкции OPENXML.
Оба аргумента: и flags, и ColPattern, являются необязательными. Если сопоставление не указано, предполагается использование атрибутивного сопоставления, которое является значением по умолчанию для аргумента flags.
Атрибутивное сопоставление
При присвоении аргументу flags в OPENXML значения 1 (XML_ATTRIBUTES) указывается атрибутивное сопоставление. Если аргумент flags содержит XML_ ATTRIBUTES, демонстрируемый набор строк предоставляет или потребляет строки, где каждый элемент XML представлен в виде строки. XML-атрибуты сопоставляются с атрибутами, определенными в SchemaDeclaration или предоставленными Tablename в предложении WITH, на основе соответствия имен. Соответствие имен означает, что атрибуты XML, имеющие определенное имя, хранятся в столбце набора строк с тем же именем.
Если имя столбца отличается от имени атрибута, с которым оно сопоставлено, должен быть указан аргумент ColPattern.
Если XML-атрибут имеет квалификатор пространства имен, имя столбца в наборе строк должно также иметь квалификатор.
Сопоставление, ориентированное на элементы
При присвоении аргументу flags в OPENXML значения 2 (XML_ELEMENTS) указывается сопоставление, ориентированное на элементы. Оно подобно атрибутивному сопоставлению, за исключением следующих отличий:
Соответствие имен в примере сопоставления: при сопоставлении столбца с элементом XML с тем же именем выбираются простые подэлементы, если не указан шаблон на уровне столбца. В процессе получения, если подэлемент является составным, поскольку содержит дополнительные подэлементы, столбцу присваивается значение NULL. При этом значения атрибутов подэлементов игнорируются.
В случае с несколькими подэлементами, имеющими одно и то же имя, возвращается первый узел.