8 Replies Latest reply: Jul 18, 2013 12:29 PM by H.Yilmaz RSS

    XML Schema validation

    H.Yilmaz

      Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

       

      Hello everybody,

       

      i have a xsd file in a dba directory and register it in my programm. The first time the validation works fine, but by the next call of the below programm code i am getting error:

       

      Error: ORA-31000: Resource '' is not an XDB schema document

       

      Any suggestion?

       

      One more Question: I want the program to take always the new Version of the xsd file, thatswhy it will be registered everytime the programm starts (when it is already existing).

      Is there any other way to let the programm know the latest version of the xsd file?

       

      Thank you in advice!

       

       

      select count(1) into l_row_count
        from user_xml_schemas
        where schema_url = 'test.xsd';
      
        if l_row_count > 0 then
          DBMS_XMLSCHEMA.deleteSchema('test.xsd', dbms_xmlSchema.DELETE_CASCADE_FORCE);
         
          DBMS_XMLSCHEMA.REGISTERSCHEMA(
              schemaurl => 'test.xsd',
              schemadoc => BFILENAME ('XSD_FILES','test.xsd')
              , local     => TRUE
              , genTypes  => FALSE
              , genbean   => FALSE
              , genTables => FALSE);
        else
           DBMS_XMLSCHEMA.REGISTERSCHEMA(
              schemaurl => 'test.xsd',
              schemadoc => BFILENAME ('XSD_FILES','test.xsd')
              , local     => TRUE
              , genTypes  => FALSE
              , genbean   => FALSE
              , genTables => FALSE);
        end if;
        -------------------------- ERROR after validation----------------------------------
          if xmlDoc.isSchemaValid() = 1 then
            dbms_output.put_line('Schema is Valid');
          else
            xmlDoc.schemaValidate();
          end if;
      
        • 1. Re: XML Schema validation
          odie_63

          i have a xsd file in a dba directory and register it in my programm. The first time the validation works fine, but by the next call of the below programm code i am getting error:

           

          Error: ORA-31000: Resource '' is not an XDB schema document

           

          Any suggestion?

          Which line of your program produces the error?

           

           

          Is there any other way to let the programm know the latest version of the xsd file?

          I'm afraid not.

          You have to delete/register again each time.

          • 2. Re: XML Schema validation
            H.Yilmaz

            Hi odie,

             

            thank you for the response. The error will be produced when trying to validate the xml:

            It goes in the else part and raises the exception after calling schemaValidate();

             

            if xmlDoc.isSchemaValid() = 1 then 
              dbms_output.put_line('Schema is Valid');
            else
              xmlDoc.schemaValidate();
            end if;
            
            • 3. Re: XML Schema validation
              odie_63

              Could you post the root element of the input XML ?

              Is there an xsi:noNamespaceSchemaLocation or xsi:schemaLocation attribute?

               

              Is xmlDoc variable schema-based ?

              • 4. Re: XML Schema validation
                H.Yilmaz

                Here you get the whole programm code. I placed know the xml schema directly as a xmltype variable:

                 

                declare
                  l_xml xmltype;
                  l_xml_test xmltype;
                  l_xsd XMLTYPE;
                  l_v_schemaURL    VARCHAR2 (256) := 'test_schema.xsd';
                  l_row_count NUMBER := 0;
                  res BOOLEAN;
                begin
                   l_xsd := XMLTYPE('<?xml version="1.0" encoding="ISO-8859-1" ?>
                                      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                                      <xs:element name="GROUP">
                                        <xs:complexType>
                                          <xs:sequence>
                                          <xs:element name="ROW">
                                          <xs:complexType>
                                          <xs:sequence>
                                            <xs:element name="COL1" type="xs:string"/>
                                            <xs:element name="COL2" type="xs:string"/>
                                            <xs:element name="COL3" type="xs:string"/>
                                          </xs:sequence>
                                          </xs:complexType>
                                          </xs:element> 
                                          </xs:sequence>
                                        </xs:complexType>
                                      </xs:element>
                                      </xs:schema> ');
                   l_xml := XMLTYPE('<?xml version="1.0" encoding="UTF-8"?> 
                    <GROUP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test_schema.xsd">
                            <ROW>
                              <COL1>123456</COL1>
                              <COL2>Hello</COL2>
                              <COL3>World</COL3>
                            </ROW>
                     </GROUP>');
                  select count(1) into l_row_count
                  from user_xml_schemas
                  where schema_url = l_v_schemaURL;
                  
                  if l_row_count > 0 then
                    DBMS_XMLSCHEMA.deleteSchema(l_v_schemaURL, dbms_xmlSchema.DELETE_CASCADE_FORCE);
                    
                    DBMS_XMLSCHEMA.REGISTERSCHEMA(
                        schemaurl => l_v_schemaURL,
                        schemadoc => l_xsd
                        , local     => TRUE
                        , genTypes  => FALSE
                        , genbean   => FALSE
                        , genTables => FALSE
                        );       
                  else 
                  
                     DBMS_XMLSCHEMA.REGISTERSCHEMA(
                        schemaurl => l_v_schemaURL,
                        schemadoc => l_xsd
                        , local     => TRUE
                        , genTypes  => FALSE
                        , genbean   => FALSE
                        , genTables => FALSE
                        ); 
                 
                  end if;
                       
                  if l_xml.isSchemaValid() = 1 then
                    dbms_output.put_line('Schema is Valid');
                  else
                    l_xml.schemaValidate();   
                  end if;
                exception when others then
                  dbms_output.put_line ('Error: ' || SQLERRM);
                end;
                

                 

                After first call following error comes up:

                Error: ORA-19030: Method invalid for non-schema based XML Documents.

                 

                After second call following error comes up:

                Error: ORA-31000: Resource '' is not an XDB schema document

                • 5. Re: XML Schema validation
                  odie_63

                  After first call following error comes up:

                  Error: ORA-19030: Method invalid for non-schema based XML Documents.

                  The schemaValidate method only works on schema-based XMLType instance.

                  An XMLType instance is schema-based if one of these conditions is true

                  • the document possesses an xsi:noNamespaceSchemaLocation or xsi:schemaLocation and the target schema is registered in the db at the time the XMLType is instantiated
                  • the XMLType has been constructed using the createSchemaBasedXML method

                   

                  The first error you got is due to the first condition not fulfilled entirely : the doc possesses the xsi attribute but on first call, no schema has been registered yet.

                   

                  After second call following error comes up:

                  Error: ORA-31000: Resource '' is not an XDB schema document

                  That second error is a little more tricky to explain.

                  On second call, a schema does exist in the db and the XMLType instance is created schema-based : that's OK so far.

                  However, since the schema is deleted, the schema-based status of the XMLType instance is no longer valid, even though the exact same schema is registered afterwards (something to do with the internal ID of the schema associated with the XML instance).

                   

                  To handle this situation, for example, you can always instantiate the XMLType after dealing with the schema, or you can use the createSchemaBasedXML method before validation.

                  In your example, you've hardcoded the input XML but in a real case, the correct solution to apply heavily depends on how the XML is built and where it comes from.

                   

                  Example of the first solution :

                  DECLARE

                   

                    l_xml xmltype; 

                    l_xsd XMLTYPE; 

                    l_v_schemaURL    VARCHAR2 (256) := 'test_schema.xsd'; 

                   

                    schema_doesnt_exist exception;

                    pragma exception_init (schema_doesnt_exist, -31000);

                   

                  BEGIN

                   

                    l_xsd := XMLTYPE('<?xml version="1.0" encoding="ISO-8859-1" ?> 

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

                                       <xs:element name="GROUP"> 

                                         <xs:complexType> 

                                           <xs:sequence> 

                                           <xs:element name="ROW"> 

                                           <xs:complexType> 

                                           <xs:sequence> 

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

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

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

                                           </xs:sequence> 

                                           </xs:complexType> 

                                           </xs:element>  

                                           </xs:sequence> 

                                         </xs:complexType> 

                                       </xs:element> 

                                       </xs:schema> '); 

                   

                   

                    begin 

                       DBMS_XMLSCHEMA.deleteSchema(l_v_schemaURL, dbms_xmlSchema.DELETE_CASCADE_FORCE);

                    exception

                      when schema_doesnt_exist then

                        null;

                    end;

                   

                   

                    DBMS_XMLSCHEMA.REGISTERSCHEMA( 

                      schemaurl => l_v_schemaURL

                    , schemadoc => l_xsd 

                    , local     => TRUE 

                    , genTypes  => FALSE 

                    , genbean   => FALSE 

                    , genTables => FALSE 

                    );  

                       

                    l_xml := XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>  

                          <GROUP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test_schema.xsd"> 

                                  <ROW> 

                                    <COL1>123456</COL1> 

                                    <COL2>Hello</COL2> 

                                    <COL3>World</COL3> 

                                  </ROW> 

                           </GROUP>') ; 

                             

                     if l_xml.isSchemaValid() = 1 then 

                       dbms_output.put_line('Schema is Valid'); 

                     else 

                       l_xml.schemaValidate();    

                     end if; 

                   

                  END; 

                  /

                  • 6. Re: XML Schema validation
                    H.Yilmaz

                    Thank you again for the response!

                     

                    I will use this programm in a PLSQL Function which gets a XMLTYPE as input paramter. This is the reason why i am first instanciate the xmltype.

                     

                    I followed your suggestion with the member function createSchemaBasedXML. Now the first Call is working fine (before the first call, of course i deleted the existing schema) .

                    The second call give me again same errror: Error: ORA-31000: Resource '' is not an XDB schema document

                     

                    Please see line 63:   l_xml_test := l_xml.createSchemaBasedXML(l_v_schemaURL);

                     

                     

                     

                     

                    declare
                      l_xml xmltype;
                      l_xml_test xmltype;
                      l_xsd XMLTYPE;
                      l_v_schemaURL    VARCHAR2 (256) := 'test_schema.xsd';
                      l_row_count NUMBER := 0;
                      res BOOLEAN;
                    begin
                       l_xsd := XMLTYPE('<?xml version="1.0" encoding="ISO-8859-1" ?>
                                          <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                                          <xs:element name="GROUP">
                                            <xs:complexType>
                                              <xs:sequence>
                                              <xs:element name="ROW">
                                              <xs:complexType>
                                              <xs:sequence>
                                                <xs:element name="COL1" type="xs:string"/>
                                                <xs:element name="COL2" type="xs:string"/>
                                                <xs:element name="COL3" type="xs:string"/>
                                              </xs:sequence>
                                              </xs:complexType>
                                              </xs:element> 
                                              </xs:sequence>
                                            </xs:complexType>
                                          </xs:element>
                                          </xs:schema> ');
                       l_xml := XMLTYPE('<?xml version="1.0" encoding="UTF-8"?> 
                        <GROUP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test_schema.xsd">
                                <ROW>
                                  <COL1>123456</COL1>
                                  <COL2>Hello</COL2>
                                  <COL3>World</COL3>
                                </ROW>
                         </GROUP>');
                      select count(1) into l_row_count
                      from user_xml_schemas
                      where schema_url = l_v_schemaURL;
                      
                      if l_row_count > 0 then
                        DBMS_XMLSCHEMA.deleteSchema(l_v_schemaURL, dbms_xmlSchema.DELETE_CASCADE_FORCE);
                        
                        DBMS_XMLSCHEMA.REGISTERSCHEMA(
                            schemaurl => l_v_schemaURL,
                            schemadoc => l_xsd
                            , local     => TRUE
                            , genTypes  => FALSE
                            , genbean   => FALSE
                            , genTables => FALSE
                            );       
                      else 
                      
                         DBMS_XMLSCHEMA.REGISTERSCHEMA(
                            schemaurl => l_v_schemaURL,
                            schemadoc => l_xsd
                            , local     => TRUE
                            , genTypes  => FALSE
                            , genbean   => FALSE
                            , genTables => FALSE
                            ); 
                     
                      end if;
                      
                      l_xml_test := l_xml.createSchemaBasedXML(l_v_schemaURL);
                           
                      if l_xml_test.isSchemaValid() = 1 then
                        dbms_output.put_line('Schema is Valid');
                      else
                        l_xml_test.schemaValidate();   
                      end if;
                    exception when others then
                      dbms_output.put_line ('Error: ' || SQLERRM);
                    end;
                    
                    • 7. Re: XML Schema validation
                      odie_63

                      I will use this programm in a PLSQL Function which gets a XMLTYPE as input paramter. This is the reason why i am first instanciate the xmltype

                       

                      OK.

                      In this case, you have to :

                       

                      • undefine the schema on the input XMLType (if necessary) :

                        if l_xml.isSchemaBased() = 1 then

                          l_xml := l_xml.createNonSchemaBasedXML();

                        end if;

                       

                      • do the schema registration stuff
                      • then prior to validation :
                      l_xml := l_xml.createSchemaBasedXML();

                      (note that you don't have to pass in the schema url in the latter, it'll be picked up in the xsi attribute)


                      • 8. Re: XML Schema validation
                        H.Yilmaz

                        Thank you very very much!

                        This was what i needed!