Is there a way (without installing any libraries) of validating XML using a custom DTD in PHP?
My interpretation of the original question is that we have an "on board" XML file that we want to validate against an "on board" DTD file. So here's how I would implement the "interpolate a local DTD inside the DOCTYPE element" idea expressed in comments by both Soren and PayamRWD:
public function validate($xml_realpath, $dtd_realpath=null) {
$xml_lines = file($xml_realpath);
$doc = new DOMDocument;
if ($dtd_realpath) {
// Inject DTD inside DOCTYPE line:
$dtd_lines = file($dtd_realpath);
$new_lines = array();
foreach ($xml_lines as $x) {
// Assume DOCTYPE SYSTEM "blah blah" format:
if (preg_match('/DOCTYPE/', $x)) {
$y = preg_replace('/SYSTEM "(.*)"/', " [\n" . implode("\n", $dtd_lines) . "\n]", $x);
$new_lines[] = $y;
} else {
$new_lines[] = $x;
}
}
$doc->loadXML(implode("\n", $new_lines));
} else {
$doc->loadXML(implode("\n", $xml_lines));
}
// Enable user error handling
libxml_use_internal_errors(true);
if (@$doc->validate()) {
echo "Valid!\n";
} else {
echo "Not valid:\n";
$errors = libxml_get_errors();
foreach ($errors as $error) {
print_r($error, true);
}
}
}
Note that error handling has been suppressed for brevity, and there may be a better/more general way to handle the interpolation. But I have actually used this code with real data, and it works with PHP version 5.2.17.