Xml get error code: примеры (PHP)
xml_get_error_code(resource parser): int|falseФункция xml_get_error_code() возвращает числовой код ошибки XML-парсера. Она применяется при обработке XML-данных для определения типа произошедшей ошибки во время разбора документа.
Функция используется совместно с XML-парсером Expat в ситуациях, требующих обработки ошибок парсинга. Типичные сценарии включают валидацию XML-документов, обработку пользовательского ввода в XML-формате, отладку парсеров и создание систем обработки исключений для XML-данных.
Функция принимает один обязательный параметр:
- parser - ресурс XML-парсера, созданный функцией xml_parser_create()
Функция возвращает целочисленный код ошибки или FALSE в случае неудачи.
<?php
$xml_parser = xml_parser_create();
$xml_data = '<root><item>text</item>';
if (!xml_parse($xml_parser, $xml_data, true)) {
$error_code = xml_get_error_code($xml_parser);
echo "Код ошибки: $error_code\n";
echo "Текст ошибки: " . xml_error_string($error_code);
}
xml_parser_free($xml_parser);
?>Код ошибки: 5 Текст ошибки: Mismatched tag
<?php
$parser = xml_parser_create();
$invalid_xml = '<document><section></wrong_tag></document>';
if (!xml_parse($parser, $invalid_xml, true)) {
$code = xml_get_error_code($parser);
switch ($code) {
case XML_ERROR_TAG_MISMATCH:
echo "Найдена ошибка несоответствия тегов";
break;
case XML_ERROR_SYNTAX:
echo "Обнаружена синтаксическая ошибка";
break;
default:
echo "Неизвестная ошибка: $code";
}
}
xml_parser_free($parser);
?>Найдена ошибка несоответствия тегов
Для работы с XML в PHP доступны несколько альтернативных подходов:
Класс DOMDocument предоставляет более современный объектно-ориентированный интерфейс для работы с XML. Он включает методы для обработки ошибок через исключения и внутренние свойства.
SimpleXML преобразует XML-документ в объект, что упрощает доступ к данным. Ошибки обычно обрабатываются через libxml_get_errors().
XMLReader реализует потоковый парсер, эффективный для обработки больших XML-файлов. Использует стандартные методы обработки ошибок PHP.
Выбор зависит от конкретной задачи: xml_get_error_code подходит для низкоуровневой работы с Expat, тогда как DOMDocument и SimpleXML предпочтительны для манипуляций с XML-структурами, а XMLReader - для обработки больших файлов.
import xml.parsers.expat
def handle_error(code, message):
print(f"Код ошибки: {code}")
print(f"Сообщение: {message}")
parser = xml.parsers.expat.ParserCreate()
parser.ErrorHandler = handle_error
# Некорректный XML
xml_data = '<root><item>text'
try:
parser.Parse(xml_data, True)
except Exception as e:
print(f"Исключение: {e}")const parser = new DOMParser();
const xmlString = '<root><item>text</root>';
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
const errorNodes = xmlDoc.querySelectorAll("parsererror");
if (errorNodes.length > 0) {
console.log("Обнаружена ошибка парсинга");
console.log(errorNodes[0].textContent);
} else {
console.log("XML корректен");
}-- MySQL имеет ограниченную поддержку XML
SELECT ExtractValue('<root><item>text</item></root>', '/root/item');
-- В случае ошибки возвращается NULL или сообщение об ошибкеОсновное отличие PHP-функции заключается в необходимости явного вызова xml_get_error_code после неудачного парсинга, тогда как в Python и JavaScript ошибки часто обрабатываются через исключения или специальные объекты.
<?php
$parser = xml_parser_create();
xml_parser_free($parser);
$error_code = xml_get_error_code($parser); // Неверно
var_dump($error_code);
?>Warning: xml_get_error_code(): supplied argument is not a valid XML Parser resource bool(false)
<?php
$parser = xml_parser_create();
$xml_data = '<root><item>text</item></root>';
xml_parse($parser, $xml_data, true); // Успешный парсинг
// Ошибочный вызов - нет ошибки для получения
$error_code = xml_get_error_code($parser);
echo "Код ошибки: $error_code"; // Выведет 0
?>Код ошибки: 0
<?php
$parser = xml_parser_create('UTF-8');
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
// XML с несовпадающей кодировкой
$xml_data = '<?xml version="1.0" encoding="ISO-8859-1"?><root>тест</root>';
if (!xml_parse($parser, $xml_data, true)) {
echo "Ошибка: " . xml_error_string(xml_get_error_code($parser));
}
?>Ошибка: Invalid character
В PHP 8.0 функция xml_get_error_code() претерпела следующие изменения:
- Тип параметра parser изменен с resource на XMLParser object
- Усилена строгая типизация - передача некорректного типа вызывает TypeError
- Улучшены сообщения об ошибках при передаче невалидного парсера
Пример совместимости с PHP 8:
<?php
// PHP 8: парсер является объектом
$parser = xml_parser_create();
var_dump($parser); // object(XMLParser)#1
// Работа функции остается прежней
$xml_data = '<root><item>text';
if (!xml_parse($parser, $xml_data, true)) {
$code = xml_get_error_code($parser);
echo "Код ошибки: $code";
}
?><?php
class XmlErrorHandler {
private $errors = [];
public function parseXML($xml_string) {
$parser = xml_parser_create();
xml_set_element_handler($parser, null, null);
if (!xml_parse($parser, $xml_string, true)) {
$this->errors[] = [
'code' => xml_get_error_code($parser),
'message' => xml_error_string(xml_get_error_code($parser)),
'line' => xml_get_current_line_number($parser),
'column' => xml_get_current_column_number($parser)
];
}
xml_parser_free($parser);
return empty($this->errors);
}
public function getErrors() {
return $this->errors;
}
}
$handler = new XmlErrorHandler();
$xml = '<root><item>Text<item></root>';
if (!$handler->parseXML($xml)) {
foreach ($handler->getErrors() as $error) {
echo "Ошибка {$error['code']}: {$error['message']} на строке {$error['line']}\n";
}
}
?>Ошибка 5: Mismatched tag на строке 1
<?php
function validateXMLFiles($files) {
$results = [];
foreach ($files as $file) {
$parser = xml_parser_create();
$content = file_get_contents($file);
if ($content === false) {
$results[$file] = 'Ошибка чтения файла';
continue;
}
if (!xml_parse($parser, $content, true)) {
$error_code = xml_get_error_code($parser);
$results[$file] = [
'valid' => false,
'error_code' => $error_code,
'error_text' => xml_error_string($error_code),
'line' => xml_get_current_line_number($parser)
];
} else {
$results[$file] = ['valid' => true];
}
xml_parser_free($parser);
}
return $results;
}
$files = ['file1.xml', 'file2.xml'];
$results = validateXMLFiles($files);
print_r($results);
?><?php
$parser = xml_parser_create();
$error_info = null;
xml_set_element_handler($parser,
function($parser, $name, $attrs) {
// Проверка атрибутов элемента
if ($name === 'item' && !isset($attrs['id'])) {
// Создание искусственной ошибки
trigger_error("Элемент item требует атрибут id", E_USER_WARNING);
}
},
null
);
$xml = '<root><item name="test">Content</item></root>';
// Основной парсинг
if (!xml_parse($parser, $xml, true)) {
$error_info = [
'code' => xml_get_error_code($parser),
'text' => xml_error_string(xml_get_error_code($parser))
];
}
// Дополнительная проверка пользовательских условий
if (!$error_info) {
$errors = error_get_last();
if ($errors && $errors['type'] === E_USER_WARNING) {
echo "Пользовательская ошибка: {$errors['message']}";
}
}
xml_parser_free($parser);
?>Пользовательская ошибка: Элемент item требует атрибут id
<?php
function parseLargeXML($file_path) {
$parser = xml_parser_create();
$fp = fopen($file_path, 'r');
$chunk_size = 4096;
$is_final = false;
while (!feof($fp)) {
$chunk = fread($fp, $chunk_size);
$is_final = feof($fp);
if (!xml_parse($parser, $chunk, $is_final)) {
$error_code = xml_get_error_code($parser);
echo "Ошибка в потоковом парсинге: " .
xml_error_string($error_code) .
" на позиции " . ftell($fp) . "\n";
break;
}
}
fclose($fp);
xml_parser_free($parser);
return $is_final && $error_code === 0;
}
// Имитация работы с большим файлом
$result = parseLargeXML('large_data.xml');
echo $result ? 'Парсинг успешен' : 'Обнаружены ошибки';
?>