4 Replies Latest reply on Aug 6, 2013 11:10 AM by c811e4f2-e289-458a-859f-d237450480ed

    CreateSchemaBasedXML using multiple schemas

    c811e4f2-e289-458a-859f-d237450480ed

      I am trying to perform XSD validation against an XML document within PLSQL and I'm having an issue with getting it working. 

      I have created an XMLTYPE object, which when I call isSchemaBased() against it returns 0 (false). Now obviously the XMLTYPE needs to be schema based in order to be validated, I found that you can make a schema based version by calling createSchemaBasedXML against the XMLTYPE. The problem I am having is that my schema is broken into two parts (combining the schema files is not an option unfortunately), which means that when I try and createSchemaBasedXML specifying the main schema it fails because it is unable to resolve a reference which is imported from the second XSD document.

       

      -- lxml is the XMLTYPE which has been populated with the XML before this point

      dbms_xmlschema
      .registerSchema(
        schemaURL
      => mainSchemaURL,
        schemaDoc
      => mainSchemaDoc,
        local
      => true,
        genTypes
      => true,
        genTables
      => false,
        force
      => true,
        enableHierarchy
      => dbms_xmlschema.ENABLE_HIERARCHY_NONE);

      dbms_xmlschema
      .registerSchema(
        schemaURL
      => importedSchemaURL,
        schemaDoc
      => importedSchemaDoc,
        local
      => true,
        genTypes
      => true,
        genTables
      => false,
        force
      => true,
        enableHierarchy
      => dbms_xmlschema.ENABLE_HIERARCHY_NONE);

      if lxml.isSchemaBased() = 1 then
        dbms_output
      .put_line('Schema based');
      else
        dbms_output
      .put_line('Non-schema based');
      end if;

      dbms_ouput
      .put_line('About to apply schema');
      lxml
      := lxml.createSchemaBasedXML(mainSchemaURL);
      dbms_ouput
      .put_line('We don't get this far');

      lxml
      := lxml.createSchemaBasedXML(importedSchemaURL);
       

      Is there any way of being able to import both the mainSchemaURL and the importedSchemaURL at the same time so that the imported schema references within the main schema don't cause the failure;

      ORA-31079: unable to result reference to type [type containing imported type]

      Any help or pointers would be greatly appreciated.

        • 1. Re: CreateSchemaBasedXML using multiple schemas
          odie_63

          Hi,

           

          First of all, you should have posted this in the XML DB forum.

           

          From what you've posted, the schemas are not registered correctly.

          The referenced schema (importedSchemaDoc) must be registered first, then the main schema (mainSchemaDoc), unless there are circular references in which case you did the right thing.

           

          The registration of the main schema first should have raised the error, but you used force = true, so the registration passed and the error was ignored.

           

          In order to solve this problem, you have to either :

          • delete both schemas and register them again in their dependency order
          • call DBMS_XMLSCHEMA.compileSchema to validate the main schema

           

          Again, be cautious when using the "force" option. If you don't have any circular dependencies to resolve, do not use it.

          • 2. Re: CreateSchemaBasedXML using multiple schemas
            c811e4f2-e289-458a-859f-d237450480ed

            My apologies for posting in the wrong location.

             

            As the schemas do not have any circular references I did like you suggested and moved the imported schema before the schema that references it as well as removing the forces. Unfortunately this doesn't appear to have solved the problem, the code now gets to where it is trying to register the mainSchema but fails with an exception "invalid XML document" (which is untrue as the XSD is valid).

             

            I have created some representitive XSD schemas to help explain what is going on. So in the mainSchema we import the importedSchema and then use a type that is defined within the importedSchema, if I remove all references to the importedSchema (shown in red below)

             

            then schema is registered, but obviously this then means that I am unable to validate the XML against the schema if these bits have been removed.

            mainSchema.xsd

             

            <?xml version="1.0" encoding="utf-8"?>

            <xs:schema id="App1_MainNamespace_v0_1_1"

                targetNamespace="App1/MainNamespace"

                xmlns="App1/MainNamespace"

                elementFormDefault="qualified"

                version="0.1.1"

                xmlns:xs="http://www.w3.org/2001/XMLSchema"

                xmlns:Imported="App1/ImportedNamespace">

             

                <xs:import namespace="App1/ImportedNamespace" />

             

                <xs:complexType name="mainComplexType">

                  <xs:sequence>

                    <xs:element name="JustAString" type="xs:string" />

                    <xs:element name="ImportedString" type="Imported:ImportedType" />

                  </xs:sequence>

                </xs:complexType>

            </xs:schema>

             

            importedSchema.xsd

            <?xml version="1.0" encoding="utf-8"?>

            <xs:schema id="App1_ImportedNamespace_v0_1_1"

                targetNamespace="App1/ImportedNamespace"

                xmlns="App1/ImportedNamespace"

                elementFormDefault="qualified"

                version="0.1.1"

                xmlns:xs="http://www.w3.org/2001/XMLSchema">

             

                <xs:simpleType name="ImportedType">

                  <xs:restriction base="xs:string">

                    <xs:minLength value="2" /

                  </xs:restriction>

                </xs:simpleType>

            </xs:schema>

             

            Updated registration code

            dbms_output.put_line('Before imported registration');

             

            -- Register the imported schema

            dbms_xmlschema.registerSchema(

              schemaURL => importedSchemaURL,

              schemaDoc => importedSchemaDoc,

              local => true,

              genTypes => true,

              genTables => false,

              enableHierarchy => dbms_xmlschema.ENABLE_HIERARCHY_NONE);

             

            dbms_output.put_line('Before main registration');

             

            -- Register the main schema

            dbms_xmlschema.registerSchema(

              schemaURL => mainSchemaURL,

              schemaDoc => mainSchemaDoc,

              local => true,

              genTypes => true,

              genTables => false,

              enableHierarchy => dbms_xmlschema.ENABLE_HIERARCHY_NONE);

             

            -- Does not reach this point

            dbms_output.put_line('Before imported compilation');

             

            dbms_xmlschema.compileSchema(importedSchemaURL);

             

            dbms_output.put_line('Before main compilation');

             

            dbms_xmlschema.compileSchema(mainSchemaURL);

             

            Any suggestions of other things that may help will be greatly appreciated.

            • 3. Re: CreateSchemaBasedXML using multiple schemas
              odie_63

              the code now gets to where it is trying to register the mainSchema but fails with an exception "invalid XML document" (which is untrue as the XSD is valid).

              This was probably not the complete error message.

              When I run your example I get :

               

              ORA-31154: invalid XML document

              ORA-19202: Error occurred in XML processing

              LSX-00023: unknown namespace URI "App1/ImportedNamespace"

              ORA-06512: at "XDB.DBMS_XMLSCHEMA_INT", line 3

              ORA-06512: at "XDB.DBMS_XMLSCHEMA", line 14

              ORA-06512: at line 4

               

              Oracle is not able to resolve the definition of the imported type.

              I know the specs don't make it mandatory but we also need to specify the schemaLocation in the import directive :

              <xs:import namespace="App1/ImportedNamespace" schemaLocation="importedSchemaURL.xsd"/>

               

              Complete test case :

              -- Register the imported schema

              begin

               

                dbms_xmlschema.registerSchema(

                  schemaURL => 'importedSchemaURL.xsd',

                  schemaDoc => '<?xml version="1.0" encoding="utf-8"?>

                <xs:schema id="App1_ImportedNamespace_v0_1_1"

                    targetNamespace="App1/ImportedNamespace"

                    xmlns="App1/ImportedNamespace"

                    elementFormDefault="qualified"

                    version="0.1.1"

                    xmlns:xs="http://www.w3.org/2001/XMLSchema">

                    <xs:simpleType name="ImportedType">

                      <xs:restriction base="xs:string">

                        <xs:minLength value="2" />

                      </xs:restriction>

                    </xs:simpleType>

                </xs:schema>',

                  local => true,

                  genTypes => false,

                  genTables => false,

                  enableHierarchy => dbms_xmlschema.ENABLE_HIERARCHY_NONE

                );

               

              end;

              /

               

              -- Register the main schema

              begin

               

                dbms_xmlschema.registerSchema(

                  schemaURL => 'mainSchemaURL.xsd',

                  schemaDoc => '<?xml version="1.0" encoding="utf-8"?>

                <xs:schema id="App1_MainNamespace_v0_1_1"

                    targetNamespace="App1/MainNamespace"

                    xmlns="App1/MainNamespace"

                    elementFormDefault="qualified"

                    version="0.1.1"

                    xmlns:xs="http://www.w3.org/2001/XMLSchema"

                    xmlns:Imported="App1/ImportedNamespace">

                    <xs:import namespace="App1/ImportedNamespace" schemaLocation="importedSchemaURL.xsd"/>

                    <xs:complexType name="mainComplexType">

                      <xs:sequence>

                        <xs:element name="JustAString" type="xs:string" />

                        <xs:element name="ImportedString" type="Imported:ImportedType" />

                      </xs:sequence>

                    </xs:complexType>

                    <xs:element name="root" type="mainComplexType"/>

                   </xs:schema>',

                  local => true,

                  genTypes => false,

                  genTables => false,

                  enableHierarchy => dbms_xmlschema.ENABLE_HIERARCHY_NONE

                );

               

              end;

              /

               

              Besides the schemaLocation attribute, I've just added a root element in the main schema, and registered both with genTypes = false (use that option if you don't intend to use object-relational storage).

               

              Validation test :

              SQL> declare

                2

                3    doc xmltype := xmltype(

                4  '<root xmlns="App1/MainNamespace"

                5         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                6         xsi:schemaLocation="App1/MainNamespace mainSchemaURL.xsd">

                7    <JustAString>ABC</JustAString>

                8    <ImportedString>X</ImportedString>

                9  </root>');

              10

              11  begin

              12

              13   doc.schemaValidate();

              14

              15  end;

              16  /

              declare

              *

              ERROR at line 1:

              ORA-31154: invalid XML document

              ORA-19202: Error occurred in XML processing

              LSX-00221: "X" is too short (minimum length is 2)

              ORA-06512: at "SYS.XMLTYPE", line 354

              ORA-06512: at line 13

               

              Seems to work

              • 4. Re: CreateSchemaBasedXML using multiple schemas
                c811e4f2-e289-458a-859f-d237450480ed

                Thank you, the suggestions you made have solved that problem