Pokud chceme využít validaci XML dokumentů pomocí XML Schema v databázi Oracle 9i (a vyšší), je nutné nejprve zjistit, jestli vůbec vaše databáze tuto možnost podporuje. Zda databáze obsahuje potřebnou knihovnu zjistíte následujícím způsobem.:

[English version – Validating XML with XMLSchema in Oracle database]

SQL> select comp_name from dba_registry;

Moje testovací databáze verze Oracle 9i obsahuje následujícím komponenty:

comp_name
Oracle9i Catalog Views
Oracle9i Packages and Types
JServer JAVA Virtual Machine

Jak je vidět „XML DB“ není v mé databázi nainstalována, takže provedeme její instalaci. Přihlásíme se do databáze pod účtem SYS a spustíme následující sekvenci příkazů:

SQL> create tablespace xmldb_ts datafile '/home/oracle/oradata/xmldb_ts.dbf' size 10M autoextend on maxsize unlimited extent management local uniform size 1M;

Pokud používáte v testovací databázi „managed tablespaces“, pak stačí zadat pouze:

SQL> create tablespace xmldb_ts;

Zároveň je vhodné upravit velikost „shared pool size“ takto:

SQL> alter system set shared_pool_size = 80M scope=spfile;

Pak už jenom stačí spustit instalaci XML DB:

SQL> set feedback off
SQL> @?/rdbms/admin/catqm xml_password xmldb_ts temp

Po instalaci XML DB ukazuje Oracle 9i následující seznam komponent, a voalá je tu i očekávaná „XML DB“:

comp_name
Oracle9i Catalog Views
Oracle9i Packages and Types
JServer JAVA Virtual Machine
Oracle XML Database

A teď už k vlastnímu využití „XML DB“ pro validaci XML pomocí XSD (XML Schema). K tomuto účelu si vytvoříme následující jednoduchý XSD dokument:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<xs:element name="root">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="created" type="xs:dateTime"/>
				<xs:element name="user" type="xs:string"/>
				<xs:element name="age" type="xs:integer"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>

Provedeme registraci schématu pod názvem „sample.xsd“ do databáze (stejně tak můžete použít název například ve tvaru „http://com.orgname/sample.xsd“):

BEGIN
    dbms_xmlschema.registerSchema('sample.xsd', '<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="created" type="xs:dateTime"/>
        <xs:element name="user" type="xs:string"/>
        <xs:element name="age" type="xs:integer"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>');
END;
/

Teď zkusíme vytvořit nějaký jednoduchý XML dokument validní podle našeho XSD:

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2010 rel. 3 sp1 (http://www.altova.com)-->
<root xsi:noNamespaceSchemaLocation="sample.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<created>2001-12-17T09:30:47Z</created>
	<user>String</user>
	<age>0</age>
</root>

A zkusíme otestovat, jestli je validní podle našeho XSD dokumentu tímto skriptem:

DECLARE
    xml XMLTYPE;

BEGIN
    xml := XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<root xsi:noNamespaceSchemaLocation="sample.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <created>2001-12-17T09:30:47Z</created>
  <user>String</user>
  <age>0</age>
</root>');
    XMLTYPE.schemaValidate(xml);
END;
/

A ejhle! Oracle odmítá tento validní dokument (podle Altova XML Spy 2010 rel.3 validní je!), vrací chybu:

SQL> ORA-01858: a non-numeric character was found where a numeric was expected
SQL> ORA-06512: at "SYS.XMLTYPE", line 0
SQL> ORA-06512: at line 11

Chyba není na vaší straně, ale v implementaci Oracle a nedodržení standardu formátu „xsd:dateTime“. Oracle se neumí vypořádat s koncovým znakem „Z“ pro zónu.

Pokud navíc použijete datum v tomto formátu „2010-08-11T15:11:19.0Z“, chyba Oracle se změní na následující:

SQL> ORA-01830: date format picture ends before converting entire input string
SQL> ORA-06512: at "SYS.XMLTYPE", line 0
SQL> ORA-06512: at line 11

Takže pozor na formát data!

Jediný správný formát v tomto případě je bez použití koncového znaku pro zónu „2010-08-11T15:11:19„. Takováto validace pak projde bez problémů (jediná ok):

DECLARE
    xml XMLTYPE;

BEGIN
    xml := XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<root xsi:noNamespaceSchemaLocation="sample.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <created>2010-08-11T15:11:19</created>
  <user>String</user>
  <age>0</age>
</root>');
    XMLTYPE.schemaValidate(xml);
END;
/

Pokud potřebujeme XML Schema z databáze odstranit, použijeme následující PL/SQL kód:

begin
dbms_xmlschema.deleteschema('sample.xsd',dbms_xmlschema.DELETE_CASCADE);
end;
/

Při výskytu následujících chyb, nebo jejich kombinací:

SQL> ORA-01031: insufficient privileges
SQL> ORA-06512: at "XDB.DBMS_XDBZ0", line 180
SQL> ORA-06512: at "XDB.DBMS_XDBZ", line 6
SQL> ORA-06512: at line 1
SQL> ORA-06512: at "XDB.DBMS_XMLSCHEMA_INT", line 0
SQL> ORA-06512: at "XDB.DBMS_XMLSCHEMA", line 12

…je nutné pro daného uživatele nastavit následující oprávnění:

SQL> GRANT CREATE TYPE TO USER;
SQL> GRANT ALTER SESSION TO USER;
SQL> GRANT CREATE VIEW TO USER;

…případně ještě přidat roli administrátora XML DB:

SQL> GRANT XDBADMIN TO USER;

Pokud se při registraci XML Schema objeví warning:

SQL> Warning: object created with compilation errors.
SQL> PL/SQL procedure successfully completed

…zkuste při registraci XML Schema doplnit parametry „gentypes“, „genbean“, „gentables“ při volání procedury registerSchema:

BEGIN
    dbms_xmlschema.registerSchema('sample.xsd', '<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="created" type="xs:dateTime"/>
        <xs:element name="user" type="xs:string"/>
        <xs:element name="age" type="xs:integer"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>', gentypes => true, genbean => false, gentables => false);
END;
/

Nezbývá než popřát hodně zdaru s validací XML dokumentů v databázi Oracle!

Post to Twitter

Leave a comment

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *