Следующий код должен отображать все ошибки:
<?php
// ----------------------------------------------------------------------------------------------------
// - Display Errors
// ----------------------------------------------------------------------------------------------------
ini_set('display_errors', 'On');
ini_set('html_errors', 0);
// ----------------------------------------------------------------------------------------------------
// - Error Reporting
// ----------------------------------------------------------------------------------------------------
error_reporting(-1);
// ----------------------------------------------------------------------------------------------------
// - Shutdown Handler
// ----------------------------------------------------------------------------------------------------
function ShutdownHandler()
{
if(@is_array($error = @error_get_last()))
{
return(@call_user_func_array('ErrorHandler', $error));
};
return(TRUE);
};
register_shutdown_function('ShutdownHandler');
// ----------------------------------------------------------------------------------------------------
// - Error Handler
// ----------------------------------------------------------------------------------------------------
function ErrorHandler($type, $message, $file, $line)
{
$_ERRORS = Array(
0x0001 => 'E_ERROR',
0x0002 => 'E_WARNING',
0x0004 => 'E_PARSE',
0x0008 => 'E_NOTICE',
0x0010 => 'E_CORE_ERROR',
0x0020 => 'E_CORE_WARNING',
0x0040 => 'E_COMPILE_ERROR',
0x0080 => 'E_COMPILE_WARNING',
0x0100 => 'E_USER_ERROR',
0x0200 => 'E_USER_WARNING',
0x0400 => 'E_USER_NOTICE',
0x0800 => 'E_STRICT',
0x1000 => 'E_RECOVERABLE_ERROR',
0x2000 => 'E_DEPRECATED',
0x4000 => 'E_USER_DEPRECATED'
);
if(!@is_string($name = @array_search($type, @array_flip($_ERRORS))))
{
$name = 'E_UNKNOWN';
};
return(print(@sprintf("%s Error in file \xBB%s\xAB at line %d: %s\n", $name, @basename($file), $line, $message)));
};
$old_error_handler = set_error_handler("ErrorHandler");
// other php code
?>
Единственный способ создать пустую страницу с этим кодом - это когда у вас есть ошибка в обработчике выключения. Я скопировал и вставил это из своих собственных cms без тестирования, но я уверен, что он работает.
Я придумал подход, который, кажется, работает. Я сначала загружаю схему явно, затем добавляю themn к schemacollection. Затем я загружаю XML-файл и присваиваю schemacollection его свойству схем. Решение теперь похоже на это:
uses MSXML2_TLB
That is:
// Type Lib: C:\Windows\system32\msxml4.dll
// LIBID: {F5078F18-C551-11D3-89B9-0000F81FE221}
function TfrmMain.ValidXML(
const xmlFile: String;
out err: IXMLDOMParseError): Boolean;
var
xml, xsd: IXMLDOMDocument2;
cache: IXMLDOMSchemaCollection;
begin
xsd := CoDOMDocument40.Create;
xsd.Async := False;
xsd.load('http://the.uri.com/schemalocation/schema.xsd');
cache := CoXMLSchemaCache40.Create;
cache.add('http://the.uri.com/schemalocation', xsd);
xml := CoDOMDocument40.Create;
xml.async := False;
xml.schemas := cache;
Result := xml.load(xmlFile);
if not Result then
err := xml.parseError
else
err := nil;
end;
важно использовать XMLSchemaCache40 или позже. Более ранние версии не следуют стандарту XML-схемы W3C, но только проверяют против Схемы XDR, спецификации Microsoft.
недостаток этого решения - то, что я должен загрузить схему явно. Мне кажется, что должно быть возможно получить их автоматически.
В то время как BennyBechDk мог бы быть на правильном пути, у меня есть несколько проблем с его кодом, который я собираюсь исправить ниже:
uses Classes, XMLIntf, xmlDoc, SysUtils;
function IsValidXMLDoc(aXmlDoc: IXMLDocument): boolean;
var
validateDoc: IXMLDocument;
begin
result := false; // eliminate any sense of doubt, it starts false period.
validateDoc := TXMLDocument.Create(nil);
try
validateDoc.ParseOptions := [poResolveExternals, poValidateOnParse];
validateDoc.XML := aXmlDoc.XML;
validateDoc.Active := true;
Result := True;
except
// for this example, I am going to eat the exception, normally this
// exception should be handled and the message saved to display to
// the user.
end;
end;
, Если Вы хотели, чтобы система просто повысила исключение, тогда нет никакой причины сделать его функцией во-первых.
uses Classes, XMLIntf, XMLDoc, SysUtils;
procedure ValidateXMLDoc(aXmlDoc: IXMLDocument);
var
validateDoc: IXMLDocument;
begin
validateDoc := TXMLDocument.Create(nil);
validateDoc.ParseOptions := [poResolveExternals, poValidateOnParse];
validateDoc.XML := aXmlDoc.XML;
validateDoc.Active := true;
end;
, поскольку validateDoc является интерфейсом, от него избавятся правильно, поскольку функция/процедура выходит, нет никакой потребности выполнить распоряжение самостоятельно. Если Вы называете ValidateXmlDoc и не получаете исключение тогда, это допустимо. Лично мне нравится первый вызов, IsValidXMLDoc, который возвращает true, если допустимый или ложный, если не (и не повышает исключения за пределами себя).
Я ранее проверил XML-документы с помощью следующего кода:
Uses
Classes,
XMLIntf,
SysUtils;
Function ValidateXMLDoc(aXmlDoc: IXMLDocument): boolean;
var
validateDoc: IXMLDocument;
begin
validateDoc := TXMLDocument.Create(nil);
validateDoc.ParseOptions := [poResolveExternals, poValidateOnParse];
validateDoc.XML := aXmlDoc.XML;
validateDoc.Active := true;
Result := True;
end;