Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Скидка до 20% на услуги дата-центра. Аренда серверной стойки. Colocation от 1U!

Миграция в облако #SotelCloud. Виртуальный сервер в облаке. Выбрать конфигурацию на сайте!

Виртуальная АТС для вашего бизнеса. Приветственные бонусы для новых клиентов!

Виртуальные VPS серверы в РФ и ЕС

Dedicated серверы в РФ и ЕС

По промокоду CITFORUM скидка 30% на заказ VPS\VDS

VPS/VDS серверы. 30 локаций на выбор

Серверы VPS/VDS с большим диском

Хорошие условия для реселлеров

4VPS.SU - VPS в 17-ти странах

2Gbit/s безлимит

Современное железо!

2007 г.

Как зарегистрировать схему XML в XML DB и как этим воспользоваться

Владимир Пржиялковский,
Преподаватель технологий Oracle
www.ccas.ru/prz
 Чиновник по особым порученьям,
Который их до места проводил,
С заботливым Попова попеченьем
Сдал на руки дежурному.

А. К. Толстой. Сон Попова

Аннотация

Установленная в БД XML DB позволяет регистрировать в базе схемы XML, задающие типы документов XML. Зарегистрированная в репозитарии схема может употребляться для данных типа XMLTYPE: как хранимых в обычных таблицах, так и доступных из производных (синтезированных) таблиц типа XMLTYPE. В статье показано на примерах, как это делать.

Введение

Эта статья является продолжением статей «XML DB - новое измерение в организации данных в Oracle» и «Что дает репозитарий XML DB и как с ним работать». Здесь говорится о регистрации в БД пользователя схем XML, что возможно после установки XML DB (об этом рассказывалось ранее). Показано, как выполняется регистрация, и как зарегистрированную схему XML можно использовать при работе с данными типа XMLTYPE.

Как зарегистрировать схему XML

Рассмотрим несложную схему XML, определение которой создадим в файле bookCover.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="cover" type="coverType"/>
    <xsd:complexType name="coverType">
      <xsd:sequence>
        <xsd:element name="title" type="xsd:string"/>
        <xsd:element name="author" type="xsd:string"
                     maxOccurs="unbounded"/>
        <xsd:element name="publisher" type="xsd:string"/>
        <xsd:element name="pubdate" type="xsd:string"/>
        <xsd:element name="isbn" type="xsd:string"/>
        <xsd:element name="pages" type="xsd:string"/>
      </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Поместим файл bookCover.xsd в репозитарий XML DB в папку /public (любым методом: командной строкой, программно, графическим способом, по WebDAV или же по FTP). Получим ресурс /public/bookCover.xsd репозитария. Зарегистрируем схему, являющуюся содержанием этого ресурса, с помощью пользователя SCOTT.

Для возможности регистрации схемы пользователь БД должен обладать привилегиями

  • ALTER SESSION
  • CREATE TYPE
  • CREATE TABLE
  • CREATE PROCEDURE
  • CREATE TRIGGER

В версии 10 содержание роли CONNECT было сведено только к привилегии CREATE SESSION, поэтому после версии 9 пользователю SCOTT потребуется так или иначе выдать привилегию ALTER SESSION, например:

CONNECT / AS SYSDBA

GRANT ALTER SESSION TO scott;

CONNECT scott/tiger

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

ALTER SESSION SET EVENTS='31098 trace name context forever';

Регистрация:

BEGIN
DBMS_XMLSCHEMA.REGISTERSCHEMA (
  schemaurl => 'http://localhost:8080/public/bookCover.xsd'
, schemadoc => XDBURITYPE ( '/public/bookCover.xsd' )
);
END;
/

Описание схемы не обязательно заводить в репозитарии в качестве ресурса. Для регистрации можно воспользоваться и внешним файлом, явно указанным документом XML или же документом, указанным через внешний URL (подтипы URITYPE).

Проверка:

SQL> COLUMN schema_url FORMAT A50 WORD
SQL> COLUMN local      FORMAT A5
SQL> SELECT schema_url, local FROM user_xml_schemas;

SCHEMA_URL                                         LOCAL
-------------------------------------------------- -----
http://localhost:8080/public/bookCover.xsd         YES

Интерес представляют также другие поля таблицы USER_XML_SCHEMAS, не указанные в этом запросе за экономией места. Например, поле QUAL_SCHEMA_URL указывает на полное (реальное), а не сокращенное имя ресурса, созданного в результате регистрации схемы: в нашем случае /sys/schemas/SCOTT/localhost:8080/public/bookCover.xsd. Если бы регистрируя схему мы объявили ее глобальной (что требует явного указания и наличия прав), полный адрес ресурса был бы иной: /sys/schemas/PUBLIC/localhost:8080/public/bookCover.xsd.

Выдача команды ALTER SESSION выше привела к фиксации в трассировочном файле сеанса некоторых скрытых действий СУБД, например:

CREATE OR REPLACE TYPE "SCOTT"."author342_COLL" AS VARRAY(2147483647) OF VARCHAR2(4000 CHAR)
/
CREATE OR REPLACE TYPE "SCOTT"."coverType341_T" AS OBJECT ("SYS_XDBPD$"
"XDB"."XDB$RAW_LIST_T","title" VARCHAR2(4000 CHAR),"author"
"author342_COLL","publisher" VARCHAR2(4000 CHAR),"pubdate" VARCHAR2(4000 CHAR),"isbn"
VARCHAR2(4000 CHAR),"pages" VARCHAR2(4000 CHAR))NOT FINAL INSTANTIABLE / CREATE TABLE "SCOTT"."cover343_TAB" OF SYS.XMLTYPE XMLSCHEMA
"http://localhost:8080/public/bookCover.xsd" ID '6927F846BBDA487F84B9BCCEC191A059'
ELEMENT "cover" ID 2664 TYPE "SCOTT"."coverType341_T" /

Результат этих действий, а также созданную заодно триггерную процедуру "cover343_TAB$xd" (в нашем случае), можно наблюдать в таблице USER_OBJECTS. (Упражнение. Узнать из таблицы USER_OBJECTS перечень появившихся после регистрации схемы XML объектов). Обратите внимание, что сведения о таблице "cover343_TAB" не отражены в USER_TABLES, хотя представлены в прочих системных таблицах, например, в USER_TAB_COLUMNS и USER_TAB_COLS.

Эти сопутствующие объекты будут технически использоваться для организации хранения данных XMLTYPE, уточненных зарегистрированной схемой. Для возможно повторяющегося элемента author хранение организовано в виде массива VARRAY.

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

BEGIN
DBMS_XMLSCHEMA.DELETESCHEMA (
  schemaurl     => 'http://localhost:8080/public/bookCover.xsd'
, delete_option => DBMS_XMLSCHEMA.DELETE_CASCADE
);
END;
/

Для краткости (но в ущерб ясности кода) можно сразу указать цифровое значение, например в SQL*Plus:

EXECUTE DBMS_XMLSCHEMA -
        .DELETESCHEMA ( 'http://localhost:8080/public/bookCover.xsd', 3 )

Использование зарегистрированной схемы

Проверка действия схемы

Метод CREATESCHEMABASEDXML типа XMLTYPE позволяет устроить проверку соответствия документа XML схеме.

Ради краткости записи следующих примеров имя зарегистрированной схемы занесем в переменную SQL*Plus:

VARIABLE bookschema VARCHAR2 ( 100 )
EXECUTE :bookschema := 'http://localhost:8080/public/bookCover.xsd'

Следующие запросы проработают без ошибок:

SELECT
 XMLTYPE ( '<cover></cover>' ).CREATESCHEMABASEDXML ( :bookschema ) 
FROM dual
;

SELECT
 XMLTYPE ( '<cover><author>Einstein</author></cover>' )
 .CREATESCHEMABASEDXML ( :bookschema ) 
FROM dual
;

SELECT
 XMLTYPE ( 
 '
 <cover>
  <title>Java Programming with Oracle JDBC</title>
  <author>Donald Bales</author>
  <publisher>OReilly and Associates</publisher>
  <pubdate>December 2001</pubdate>
  <isbn>0-596-00088-x</isbn>
  <pages>496</pages>
 </cover>
 ' ).CREATESCHEMABASEDXML ( :bookschema ) 
FROM dual
;

Следующие запросы проработают с ошибками ввиду противоречий документа схеме:
SELECT
 XMLTYPE ( '<c/>' ).CREATESCHEMABASEDXML ( :bookschema ) 
FROM dual
;

SELECT
 XMLTYPE ( '<cover><a>Einstein</a></cover>' )
 .CREATESCHEMABASEDXML ( :bookschema ) 
FROM dual
;

SELECT
 XMLTYPE ( '<cover><title>A</title><title>B</title></cover>' )
 .CREATESCHEMABASEDXML ( :bookschema ) 
FROM dual
;

Использование для дополнительной типизации XMLTYPE в базовых таблицах

Просто указанный XMLTYPE требует лишь, чтобы помещаемый в БД документ был правильно оформлен. Зарегистрированная в XML DB схема XML позволяет указать для размещаемых в конкретные поля документов XML-образные ограничения целостности, позволяя хранить только «годные» (valid) из них.

Создадим таблицу объектов XMLTYPE, уточненную ссылкой на зарегистрированную схему:

CREATE TABLE xtbooks OF XMLTYPE
XMLSCHEMA "http://localhost:8080/public/bookCover.xsd"
ELEMENT "cover"
;

Проверка занесения данных:

INSERT INTO xtbooks VALUES (
XMLTYPE ( '<cover><author>Einstein</author></cover>' )
);

INSERT INTO xtbooks VALUES (
 XMLTYPE ( '
 <cover>
  <title>Java Programming with Oracle JDBC</title>
  <author>Donald Bales</author>
  <publisher>OReilly and Associates</publisher>
  <pubdate>December 2001</pubdate>
  <isbn>0-596-00088-x</isbn>
  <pages>496</pages>
 </cover>
 ' ) 
);

COMMIT;

Упражнение. Проверьте реакцию СУБД на попытку вставить в таблицу XTBOOKS правильно оформленный документ XML, не соответствующий описанию схемы.

Аналогично накладываются дополнительные ограничения на данные столбца XMLTYPE в обычной таблице:

CREATE TABLE tbooks  (
  id          NUMBER ( 9 )
, description XMLTYPE
) 
XMLTYPE description STORE AS OBJECT RELATIONAL
XMLSCHEMA "http://localhost:8080/public/bookCover.xsd"
ELEMENT "cover"
;

В приведенных примерах данные в БД фактически будут храниться «объектно-реляционно», то есть будучи распределены по разным структурам БД, в том числе по спрятанным столбцам таблиц. Однако типизируя таблицу или столбец типа XMLTYPE схемой, можно потребовать фактического хранения документа в виде объекта CLOB, подобно тому, как это происходит при отсутствии типизации схемой.

Пример:

CREATE TABLE xtbooksclob OF XMLTYPE
XMLTYPE STORE AS CLOB
XMLSCHEMA "http://localhost:8080/public/bookCover.xsd"
ELEMENT "cover"
;

Упражнение. Проверить возникновение новых объектов БД и их структуры по результатам заведения таблиц XTBOOKS, TBOOKS и XTBOOKSCLOB. Воспользоваться для этого таблицами USER_OBJECTS, USER_TAB_COLS, USER_TYPES, USER_TRIGGERS, USER_LOBS.

Использование для дополнительной типизации XMLTYPE в производных таблицах (views)
При отсутствии XML DB не заперщено создавать производную таблицу (view), выдающую данные в виде таблицы документов XML (типа XMLTYPE) на основе данных из обычных таблиц. Рассмотрим, как при наличии XML DB можно дополнительно уточнить такую производную таблицу схемой XML.

В этом примере регистрируется схема, не взятая из ресурса репозитария, как ранее, а явно выписанная в виде текста XML:

BEGIN
DBMS_XMLSCHEMA.REGISTERSCHEMA (
  schemaurl => 'http://localhost:8080/public/employee.xsd'
, schemadoc => 
  '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
     <xs:element name="employee">
       <xs:complexType>
         <xs:sequence>	
           <xs:element name="ename" type="xs:string"/>
           <xs:element name="job" type="xs:string"/>
           <xs:element name="sal" type="xs:integer"/>
         </xs:sequence>
         <xs:attribute name="empno" type="xs:integer"/>
       </xs:complexType>
     </xs:element>
   </xs:schema>
  '
);
END;
/

Пример создания производной таблицы:

CREATE OR REPLACE VIEW empxml_schema_view OF XMLTYPE 
XMLSCHEMA "http://localhost:8080/public/employee.xsd"
ELEMENT "employee"
WITH OBJECT ID
 ( EXTRACT ( SYS_NC_ROWINFO$, '/employee/@empno' ).GETNUMBERVAL ( ) )
AS 
SELECT
  XMLELEMENT (
    "employee"
  , XMLATTRIBUTES ( e.empno AS "empno" )
  , XMLFOREST ( e.ename AS "ename", e.job AS "job", e.sal AS "sal" )
  )
FROM emp e
;

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

SELECT VALUE ( v ).ISSCHEMAVALID ( ) FROM empxml_schema_view v;

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

SELECT VALUE ( v ).ISSCHEMAVALID ( ) FROM empxml_view v;

SELECT
  VALUE ( v )
  .ISSCHEMAVALID ( 'http://localhost:8080/public/employee.xsd' ) 
FROM empxml_view v
;

Упражнение. Внести в схему http://localhost:8080/public/employee.xsd пользователя SCOTT изменение (снять с регистрации и зарегистрировать исправленный текст). Заменить в схеме существующее описание зарплаты:

           <xs:element name="sal" type="xs:integer"/>

на следующее:

           <xs:element name="sal">
             <xs:simpleType>
               <xs:restriction base="xs:integer">
                 <xs:maxInclusive value="1500"/> 
                 <xs:minInclusive value="1000"/>
               </xs:restriction>
             </xs:simpleType>
           </xs:element>

Проверить поведение последних трех упоминавшихся выше запросов.

Последний пример показывает использование чуть более сложных ограничений целостности на структуру и данные документов XML (сформулированы минимальное и максимальное значения зарплат).

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

✅ Дешевый VPS-хостинг на AMD EPYC: 1vCore, 3GB DDR4, 15GB NVMe всего за €3,50!

🔥 Anti-DDoS защита 12 Тбит/с!

VPS в России, Европе и США

Бесплатная поддержка и администрирование

Оплата российскими и международными картами

🔥 VPS до 5.7 ГГц под любые задачи с AntiDDoS в 7 локациях

💸 Гифткод CITFORUM (250р на баланс) и попробуйте уже сейчас!

🛒 Скидка 15% на первый платеж (в течение 24ч)

Новости мира IT:

Архив новостей

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 7861149
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2019 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...