SQL + DTD

How to select xml with DTD ?

  • Imagine this XML code
SQL> select xmltype(
'<!DOCTYPE FOO SYSTEM "/public/test/foo.dtd"><FOO/>', 
wellformed => 1) xml 
from dual;

XML
-----------------------------------------------------
<!DOCTYPE FOO SYSTEM "/public/test/foo.dtd"><FOO/>

Most validations are done with XSD and not DTD, so it is not that easy, even google probably lead you here 😉

  • Create the dtd in XDB
declare
b boolean;
begin 
b := dbms_xdb.createfolder('/public/test');
b := dbms_xdb.createresource(
'/public/test/foo.dtd',
'<!ELEMENT FOO (BAR*)>');
end;
/
  • Use DBMS_XMLDOM and CLOB
WITH
FUNCTION f(
doc xmltype, 
name varchar2 default null, 
sysid varchar2 default null, 
pubid varchar2 default null) 
RETURN xmltype IS
dom DBMS_XMLDOM.domdocument;
tmp CLOB;
BEGIN
dom := dbms_xmldom.NEWDOMDOCUMENT(doc);
DBMS_XMLDOM.SETDOCTYPE(dom,name,sysid,pubid);
DBMS_LOB.CREATETEMPORARY(tmp,true,DBMS_LOB.SESSION);
DBMS_XMLDOM.writeToClob(DBMS_XMLDOM.makeNode(dom), tmp);
RETURN XMLTYPE(tmp);
END;
SELECT f(xmlelement(foo),'FOO','/public/test/foo.dtd','') XML
/

XML
--------------------------------------------------------------------------------
<!DOCTYPE FOO SYSTEM "/public/test/foo.dtd">
<FOO/>
  • Cleanup
select * from resource_view;
exec dbms_xdb.DeleteResource('/public/test/foo.dtd');
exec dbms_xdb.DeleteResource('/public/test');

Largely inspired by arkzoyd