This discussion is archived
7 Replies Latest reply: May 24, 2012 11:38 AM by odie_63 RSS

Error with DTD duplicated SYSTEM inclusion

939282 Newbie
Currently Being Moderated
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 Guru
    Currently Being Moderated
    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 Guru
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Oracle ACE Director
    Currently Being Moderated
    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 Guru
    Currently Being Moderated
    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 Newbie
    Currently Being Moderated
    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 Guru
    Currently Being Moderated
    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.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points