7 Replies Latest reply: May 24, 2012 1:38 PM by odie_63 RSS

    Error with DTD duplicated SYSTEM inclusion

    939282
      I'm working with one of the latest releases
      Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
      PL/SQL Release 11.2.0.1.0 - Production
      "CORE     11.2.0.1.0     Production"
      TNS for Linux: Version 11.2.0.1.0 - Production
      NLSRTL Version 11.2.0.1.0 - Production

      I'm trying to insert xml into an XMLType table, and validate it with a DTD. To achieve this i created a folder /xmlmine/dtd and applied this acl to it
      <acl description="dilbertacl" xmlns="http://xmlns.oracle.com/xdb/acl.xsd" xmlns:dav="DAV:" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd                                    http://xmlns.oracle.com/xdb/acl.xsd" shared="true">
            <ace>
              <grant>true</grant>
              <principal>DILBERT</principal>
              <privilege>
                <dav:all/>
              </privilege>
            </ace>
          </acl>
      i then uploaded this dtd to play.dtd with
      DECLARE
        b BOOLEAN;
      BEGIN
        b := DBMS_XDB.createResource('/xmlmine/dtd/play.dtd',bfilename('dtds', 'play.dtd'));
      END;
      and i can see it with
      select xdburitype('/xmlmine/dtd/play.dtd').getCLOB() from dual;
      
      <!-- DTD for Shakespeare    J. Bosak    1994.03.01, 1997.01.02 -->
      <!-- Revised for case sensitivity 1997.09.10 -->
      <!-- Revised for XML 1.0 conformity 1998.01.27 (thanks to Eve Maler) -->
      
      <!ENTITY amp "&#38;">
      <!ELEMENT PLAY     (TITLE, FM, PERSONAE, SCNDESCR, PLAYSUBT, INDUCT?, PROLOGUE?, ACT+, EPILOGUE?)>
      <!ELEMENT TITLE    (#PCDATA)>
      <!ELEMENT FM       (P+)>
      <!ELEMENT P        (#PCDATA)>
      <!ELEMENT PERSONAE (TITLE, (PERSONA | PGROUP)+)>
      <!ELEMENT PGROUP   (PERSONA+, GRPDESCR)>
      <!ELEMENT PERSONA  (#PCDATA)>
      <!ELEMENT GRPDESCR (#PCDATA)>
      <!ELEMENT SCNDESCR (#PCDATA)>
      <!ELEMENT PLAYSUBT (#PCDATA)>
      <!ELEMENT INDUCT   (TITLE, SUBTITLE*, (SCENE+|(SPEECH|STAGEDIR|SUBHEAD)+))>
      <!ELEMENT ACT      (TITLE, SUBTITLE*, PROLOGUE?, SCENE+, EPILOGUE?)>
      <!ELEMENT SCENE    (TITLE, SUBTITLE*, (SPEECH | STAGEDIR | SUBHEAD)+)>
      <!ELEMENT PROLOGUE (TITLE, SUBTITLE*, (STAGEDIR | SPEECH)+)>
      <!ELEMENT EPILOGUE (TITLE, SUBTITLE*, (STAGEDIR | SPEECH)+)>
      <!ELEMENT SPEECH   (SPEAKER+, (LINE | STAGEDIR | SUBHEAD)+)>
      <!ELEMENT SPEAKER  (#PCDATA)>
      <!ELEMENT LINE     (#PCDATA | STAGEDIR)*>
      <!ELEMENT STAGEDIR (#PCDATA)>
      <!ELEMENT SUBTITLE (#PCDATA)>
      <!ELEMENT SUBHEAD  (#PCDATA)>
      when i proceed to insert with
      INSERT INTO sestable VALUES (XMLType(bfilename('xmls', 'all_well.xml'),nls_charset_id('AL32UTF8')));
      the top of the xml document looks like
      <?xml version="1.0" encoding="WINDOWS-1252"?>
      <!DOCTYPE PLAY SYSTEM "/xmlmine/dtd/play.dtd" [
      <!ELEMENT PLAY (TITLE, FM, PERSONAE, SCNDESCR, PLAYSUBT, INDUCT?, PROLOGUE?, ACT+, EPILOGUE?)>
      <!ELEMENT TITLE (#PCDATA)>
      <!ELEMENT FM (P+)>
      
      ........
      
      <!ELEMENT SUBTITLE (#PCDATA)>
      <!ELEMENT SUBHEAD (#PCDATA)>
      ]>
      <!-- DTD for Shakespeare    J. Bosak    1994.03.01, 1997.01.02 -->
      <!-- Revised for case sensitivity 1997.09.10 -->
      <!-- Revised for XML 1.0 conformity 1998.01.27 (thanks to Eve Maler) -->
      <PLAY>
        <TITLE>All&apos;s Well That Ends Well</TITLE>
        <FM>
          <P>Text placed in the public domain by Moby Lexical Tools, 1992.</P>
      
      ....
      
            <STAGEDIR>Exeunt</STAGEDIR>
          </EPILOGUE>
        </ACT>
      </PLAY>
      but when i try to query the table with something like
      select xtab.COLUMN_VALUE
      from sestable, XMLTable('let $i := /PLAY/ACT/SCENE/SPEECH[SPEAKER eq "DUKE"]/LINE
                      return count($i)' PASSING OBJECT_VALUE) xtab;
      i get an error
      LPX-00107:Warning: element "PLAY" has multiple declaration

      if i remove the SYSTEM keyword and simply inline the DTD everything works just fine.

      I suspect the parser is inlining the DTD but not removing the SYSTEM directive, thus including the DTD twice, hence the error. Any suggestion on how to solve this?

      Thanks in advance
        • 1. Re: Error with DTD duplicated SYSTEM inclusion
          odie_63
          Works for me on 11.2.0.2 :
          SQL> create table plays of xmltype;
           
          Table created
           
          SQL> 
          SQL> declare
            2    res boolean;
            3  begin
            4    res := DBMS_XDB.createResource('/public/dtd/play.dtd', bfilename('TEST_DIR', 'play.dtd'));
            5  end;
            6  /
           
          PL/SQL procedure successfully completed
           
          SQL> insert into plays values (xmltype(bfilename('TEST_DIR', 'all_well.xml'), nls_charset_id('AL32UTF8')));
           
          1 row inserted
           
          SQL> commit;
           
          Commit complete
           
          SQL> set long 500
          SQL> select object_value from plays;
           
          OBJECT_VALUE
          --------------------------------------------------------------------------------
          <?xml version="1.0"?>
          <!DOCTYPE PLAY SYSTEM "/public/dtd/play.dtd" [
            <!-- DTD for Shakespeare    J. Bosak    1994.03.01, 1997.01.02 -->
            <!-- Revised for case sensitivity 1997.09.10 -->
            <!-- Revised for XML 1.0 conformity 1998.01.27 (thanks to Eve Maler) -->
          <!ELEMENT PLAY (TITLE, FM, PERSONAE, SCNDESCR, PLAYSUBT, INDUCT?, PROLOGUE?, ACT
          <!ELEMENT TITLE (#PCDATA)>
          <!ELEMENT FM (P+)>
          <!ELEMENT P (#PCDATA)>
          <!ELEMENT PERSONAE (TITLE, (PERSONA | PGROUP)+)>
          <!ELEMENT PGR
           
          SQL> 
          SQL> SELECT count(*)
            2  FROM plays p
            3     , XMLTable( '/PLAY/ACT/SCENE/SPEECH[SPEAKER eq "DUKE"]/LINE'
            4                 passing p.object_value ) x
            5  WHERE XMLExists( '/PLAY[TITLE=$title]'
            6                   passing p.object_value
            7                        , 'All''s Well That Ends Well' as "title" )
            8  ;
           
            COUNT(*)
          ----------
                  19
           
          • 2. Re: Error with DTD duplicated SYSTEM inclusion
            odie_63
            OK, I reproduce the issue if I use CLOB storage instead of binary XML (new default on 11.2.0.2) :
            SQL> create table plays2 of xmltype
              2  xmltype store as basicfile clob;
            
            Table created.
            
            SQL> insert into plays2 values (xmltype(bfilename('TEST_DIR', 'all_well.xml'), nls_charset_id('AL32UTF8')));
            
            1 row created.
            
            SQL> SELECT count(*)
              2  FROM plays2 p
              3     , XMLTable( '/PLAY/ACT/SCENE/SPEECH[SPEAKER eq "DUKE"]/LINE'
              4                 passing p.object_value ) x
              5  WHERE XMLExists( '/PLAY[TITLE=$title]'
              6                   passing p.object_value
              7                        , 'All''s Well That Ends Well' as "title" )
              8  ;
            SELECT count(*)
            *
            ERROR at line 1:
            ORA-31011: XML parsing failed
            ORA-19202: Error occurred in XML processing
            LPX-00107: Warning: element "PLAY" has multiple declarations
            Error at line 24
            Error at line 7
            Could you try with binary XML storage in your version?
            create table plays of xmltype
            xmltype store as securefile binary xml;
            • 3. Re: Error with DTD duplicated SYSTEM inclusion
              939282
              Thanks for your quick reply.
              It seems that inserting data as binary does stop the error from occurring, but drops the DTD validation altogether. In the lines of the table there are no signs of DOCTYPE and the following piece
              <FM>
              <P>Text placed in the public domain by Moby Lexical Tools, 1992.</P>
              <P>SGML markup by Jon Bosak, 1992-1994.</P>
              <P>
              XML version by Jon Bosak, 1996-1998.</P>
              <P>This work may be freely copied and distributed worldwide.</P>
                      <SPEECH>
                      <LINE>
                              wrong
                      </LINE>
                      </SPEECH>
              wrong
              </FM>
              or
              <PERSONAE>
                    <TITLE>Dramatis Personae</TITLE>
                    <SPEECH>
                       <LINE>
                        wrong
                   </LINE>
                    </SPEECH>
              wrong
              
              <PERSONA>KING OF FRANCE</PERSONA>
              gets accepted.
              • 4. Re: Error with DTD duplicated SYSTEM inclusion
                Marco Gralike
                Marc, can you reproduce the error on 11.2.0.2.0 with binary xml and the following event?
                SQL> ALTER SESSION 
                     SET events= '31156 trace name context forever, level 0x400';
                In other words it might be a different parser behavior issue between 11.2.0.1 and 11.2.0.2
                • 5. Re: Error with DTD duplicated SYSTEM inclusion
                  odie_63
                  Marco Gralike wrote:
                  Marc, can you reproduce the error on 11.2.0.2.0 with binary xml and the following event?
                  Just tried, no difference.
                  • 6. Re: Error with DTD duplicated SYSTEM inclusion
                    939282
                    What should I do now, since binary XML does not seems to validate? Is there any other way to validate the XML document with a DTD besides directly copying and pasting the DTD in the file?
                    If this is a bug should I report it or you can do / have already done that?
                    • 7. Re: Error with DTD duplicated SYSTEM inclusion
                      odie_63
                      What should I do now, since binary XML does not seems to validate? Is there any other way to validate the XML document with a DTD besides directly copying and pasting the DTD in the file?
                      Well, as a workaround, you can disable DTD validation after the document has been inserted in the table.
                      SQL> select storage_type from user_xml_tables where table_name = 'PLAYS2';
                      
                      STORAGE_TYPE
                      -----------------
                      CLOB
                      
                      SQL> SELECT count(*)
                        2  FROM plays2 p
                        3     , XMLTable( '/PLAY/ACT/SCENE/SPEECH[SPEAKER eq "DUKE"]/LINE'
                        4                 passing p.object_value ) x
                        5  WHERE XMLExists( '/PLAY[TITLE=$title]'
                        6                   passing p.object_value
                        7                        , 'All''s Well That Ends Well' as "title" )
                        8  ;
                      SELECT count(*)
                      *
                      ERROR at line 1:
                      ORA-31011: XML parsing failed
                      ORA-19202: Error occurred in XML processing
                      LPX-00107: Warning: element "PLAY" has multiple declarations
                      Error at line 24
                      Error at line 7
                      
                      
                      SQL> alter session set events '31156 trace name context forever, level 2';
                      
                      Session altered.
                      
                      SQL> SELECT count(*)
                        2  FROM plays2 p
                        3     , XMLTable( '/PLAY/ACT/SCENE/SPEECH[SPEAKER eq "DUKE"]/LINE'
                        4                 passing p.object_value ) x
                        5  WHERE XMLExists( '/PLAY[TITLE=$title]'
                        6                   passing p.object_value
                        7                        , 'All''s Well That Ends Well' as "title" )
                        8  ;
                      
                        COUNT(*)
                      ----------
                              19
                      If this is a bug should I report it or you can do / have already done that?
                      I didn't see anything in the documentation regarding DTD validation vs. binary XML, so yes I think you should report it to Oracle Support.