Моя интерпретация первоначального вопроса заключается в том, что у нас есть XML-файл «на борту», который мы хотим проверить по DTD-файлу «на борту». Итак, вот как я мог бы реализовать идею «интерполировать локальное DTD внутри элемента DOCTYPE», выраженную в комментариях как Soren, так и 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);
}
}
}
Обратите внимание, что для краткости обработка ошибок была подавлена, и может существовать лучший / более общий способ обработки интерполяции. Но я фактически использовал этот код с реальными данными, и он работает с версией PHP 5.2.17.