There are some stand-alone DTD files that I would like to parse in my Delphi application with MSXML6. The DTD file content looks similar to:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ATTLIST to
type CDATA #FIXED "email"
default CDATA #FIXED "you@foo.bar"
>
<!ELEMENT from (#PCDATA)>
<!ATTLIST from
type CDATA #FIXED "email"
default CDATA #FIXED "me@foo.bar"
>
<!ELEMENT heading (#PCDATA)>
<!ATTLIST heading
type CDATA #FIXED "string"
>
<!ELEMENT body (#PCDATA)>
<!ATTLIST body
type CDATA #FIXED "string"
>
Trying to load this data with MSXML fails with error message "Cannot have a DTD declaration outside of a DTD".
When wrapping the DTD into some DOCTYPE element like this:
<?xml version="1.0"?>
<!DOCTYPE note [
... content of DTD file above ...
]>
<note/>
the parser succeeds but does not allow to iterate over the DTD structure. The (Delphi) code to load and display the document looks like this:
var
XmlDoc : iXmlDomDocument2;
i : integer;
begin
XmlDoc := CoDomDocument60.Create();
XmlDoc.SetProperty('NewParser', FALSE);
XmlDoc.SetProperty('ProhibitDTD', FALSE);
XmlDoc.Async := FALSE;
XmlDoc.ValidateOnParse := FALSE;
XmlDoc.Load(FileName);
if ( XmlDoc.ParseError.ErrorCode <> 0 ) then
raise Exception.Create(XmlDoc.ParseError.Reason);
// This will display "note"
ShowMessage('DocType: ' + XmlDoc.Doctype.Name);
// This will display the embedded DTD as a string
ShowMessage('DTD: ' + XmlDoc.Doctype.Xml);
// These loops will display nothing
for i := 0 to XmlDoc.Doctype.Entities.Length-1 do
ShowMessage('Entity: ' + XmlDoc.Doctype.Entities[i].NodeName);
for i := 0 to XmlDoc.Doctype.Notations.Length-1 do
ShowMessage('Notation: ' + XmlDoc.Doctype.Notations[i].NodeName);
for i := 0 to XmlDoc.Doctype.ChildNodes.Length-1 do
ShowMessage('Child: ' + XmlDoc.Doctype.ChildNodes[i].NodeName);
end;
Is there a way to iterate over the DTD node structure using MSXML6?