Tcl package, [XML] DTD validation extension to [tDOM]. Usage example contributed by [RS]: ====== package require tnc ;# implies tdom #---------------------------------------- modified from expat man page proc externalEntityRefHandler {base systemId publicId} { if {![regexp {^[/a-zA-Z]+:/} $systemId]} { regsub {^[/a-zA-Z]+:} $base {} base set basedir [file dirname $base] set systemId "[set basedir]/[set systemId]" } regsub {^[/a-zA-Z]+:} $systemId "" systemId set fd [open $systemId] list channel $systemId $fd } set parser [expat -externalentitycommand externalEntityRefHandler\ -baseurl "file://[file join [pwd] $file]" \ -paramentityparsing always] tnc $parser enable foreach file [glob $argv] { if [file readable $file] { catch {$parser parsefile $file} res if {$res==""} {set res ok} puts $file:$res $parser reset } } $parser free ====== ---- The ''externalEntityRefHandler'' is freely configurable by the user. From tDOM 0.7.5, a convenience proc will be included in the release (planned for mid November 2002). ---- [dcd] 2010-09-27. Here's an example of letting tnc do all the validation. The drawback is that if it fails, you generally have no idea why. ====== # Test if an XML file can be validated against a DTD. # Input: DTD contents and the XML file contents proc validateXMLwithDTD {dtd_contents file_contents} { set all $dtd_contents append all $file_contents set parser [expat] # For tnc to validate: # - enable a parser with tnc # - parse an XML doc and its DTD # - use the created command to validate a dom tree tnc $parser enable if {[catch {set result [$parser parse $all]} err]} { return parse_error } else { tnc $parser getValidateCmd validateCmd if [catch {dom parse $file_contents domDoc} err] { return dom_parse_error } set result [validateCmd validateDocument $domDoc] if {$result == 0} { return validation_error } validateCmd delete return 0 } $parser free return unknown_error } ====== and here's a test set for it. ====== set dtd_contents { ]> } set xml_contents { } ====== !!!!!! %|[Category Package]|% !!!!!!