Xml get current column number: примеры (PHP)

Работа с xml_get_current_column_number: получение позиции в XML
Раздел: XML
xml_get_current_column_number(resource parser): int|false

Описание функции xml_get_current_column_number

Функция xml_get_current_column_number() в PHP предназначена для получения номера текущего столбца при разборе XML-документа с помощью библиотеки XML Parser (expat). Используется в процессе парсинга для точного определения позиции в строке, что особенно полезно для обработки ошибок, логирования или построения детальных отчетов о разборе документа.

Аргументы функции

Функция принимает единственный обязательный аргумент:

  • parser (ресурс) — ресурс XML-парсера, созданный функцией xml_parser_create(). Аргумент указывает на активный экземпляр парсера, из которого требуется получить текущий номер столбца.

Функция возвращает целое число — номер столбца (начиная с 1) в текущей строке, где находится указатель парсера. В случае ошибки (например, при неверном ресурсе парсера) возвращает false.

Примеры использования функции

Базовый пример получения номера столбца

Пример показывает, как получить текущий номер столбца внутри обработчика тегов:

<?php
$xml = "<root><element>Text</element></root>";
$parser = xml_parser_create();

// Обработчик начала тега
function startElement($parser, $name, $attrs) {
    $column = xml_get_current_column_number($parser);
    echo "Столбец начала тега: $column\n";
}

xml_set_element_handler($parser, "startElement", null);
xml_parse($parser, $xml, true);
xml_parser_free($parser);
?>
Столбец начала тега: 1
Пример с определением позиции в тексте

Использование функции в обработчике текстовых данных:

<?php
$xml = "<root>\n    <text>Пример текста</text>\n</root>";
$parser = xml_parser_create();

function characterData($parser, $data) {
    $column = xml_get_current_column_number($parser);
    echo "Текст: '$data' | Столбец: $column\n";
}

xml_set_character_data_handler($parser, "characterData");
xml_parse($parser, $xml, true);
?>
Текст: '\n    ' | Столбец: 1
Текст: 'Пример текста' | Столбец: 5

Альтернативные функции в PHP

В PHP существуют другие функции для получения позиции при разборе XML:

  • xml_get_current_line_number() — возвращает номер текущей строки в XML-документе. Используется вместе с xml_get_current_column_number() для точного позиционирования. Предпочтительна для логирования ошибок с указанием строки и столбца.
  • xml_get_error_code() и xml_error_string() — функции для получения кода и описания ошибок парсера. Применяются в сочетании с функциями позиционирования для детальной диагностики.

При работе с DOMDocument или SimpleXML, которые являются более высокоуровневыми API, прямых аналогов для получения номера столбца нет. Эти библиотеки автоматически обрабатывают ошибки без детального позиционирования в исходном тексте.

Альтернативы в других языках программирования

Python

В модуле xml.parsers.expat функция CurrentColumnNumber объекта парсера возвращает аналогичные данные. Пример:

import xml.parsers.expat as expat

def start_element(name, attrs):
    print(f"Столбец: {parser.CurrentColumnNumber}")

parser = expat.ParserCreate()
parser.StartElementHandler = start_element
xml = "<root><item/></root>"
parser.Parse(xml, True)
Столбец: 1
JavaScript

В браузерном JavaScript при использовании SAX-парсера (например, sax-js) аналогичная функциональность доступна через свойство column в объекте позиции. Пример:

const sax = require('sax');
const parser = sax.parser(true);
parser.onopentag = (node) => {
    console.log(`Столбец: ${parser.position.column}`);
};
parser.write("<root><test/></root>");
Столбец: 1
MySQL

В MySQL нет прямых аналогов, так как язык ориентирован на работу с базами данных, а не парсинг XML. Для извлечения данных из XML используются функции ExtractValue() или UpdateXML(), которые не предоставляют информацию о позиции в исходном документе.

Типичные ошибки использования

Передача неверного ресурса парсера

Если передать не ресурс или некорректный ресурс, функция вернет false:

<?php
$result = xml_get_current_column_number(null);
var_dump($result);
?>
bool(false)
Вызов функции после завершения парсинга

Попытка получить номер столбца после вызова xml_parser_free() приводит к ошибке:

<?php
$parser = xml_parser_create();
xml_parser_free($parser);
$column = xml_get_current_column_number($parser); // Ресурс уже освобожден
?>
Warning: xml_get_current_column_number(): supplied argument is not a valid XML Parser resource
Игнорирование пробельных символов

Функция учитывает пробелы и табуляции, что может привести к неожиданным результатам, если разработчик ожидает подсчет только значащих символов:

<?php
$xml = "   <root>"; // 3 пробела перед тегом
$parser = xml_parser_create();
function startElement($parser, $name) {
    echo "Столбец: " . xml_get_current_column_number($parser);
}
xml_set_element_handler($parser, "startElement", null);
xml_parse($parser, $xml, true);
?>
Столбец: 4

Изменения в последних версиях PHP

Функция xml_get_current_column_number() не претерпела значительных изменений в PHP 8. Основные корректировки связаны с общей поддержкой библиотеки XML Parser:

  • В PHP 8.0 улучшена обработка ошибок при передаче неверных аргументов — теперь функция вызывает предупреждение типа TypeError для некорректных ресурсов.
  • Поддержка библиотеки остается стабильной, без изменений в возвращаемых значениях или поведении.

Рекомендуется использовать последние версии PHP для получения актуальных исправлений безопасности, связанных с разбором XML.

Расширенные примеры использования

Отслеживание позиции при ошибках парсинга

Пример демонстрирует использование функции для точного указания места ошибки в XML-документе:

Пример php
<?php
$xml = "<root><unclosed>text</root>"; // Незакрытый тег
$parser = xml_parser_create();

function handleError($parser, $code, $msg) {
    $line = xml_get_current_line_number($parser);
    $column = xml_get_current_column_number($parser);
    echo "Ошибка: $msg в строке $line, столбец $column\n";
}

xml_set_element_handler($parser, null, null);
xml_set_character_data_handler($parser, null);
xml_set_default_handler($parser, null);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_set_error_handler($parser, "handleError");

if (!xml_parse($parser, $xml, true)) {
    echo "Парсинг завершился неудачно\n";
}
xml_parser_free($parser);
?>
Ошибка: Mismatched tag в строке 1, столбец 30
Анализ формата с отступами

Использование функции для проверки соответствия форматирования XML определенным стандартам отступов:

Пример php
<?php
$xml = "<root>\n  <child>value</child>\n</root>";
$parser = xml_parser_create();

function checkIndent($parser, $name, $attrs) {
    $column = xml_get_current_column_number($parser);
    if ($column != 1 && $column != 3) {
        echo "Нарушение отступа в теге $name: столбец $column\n";
    }
}

xml_set_element_handler($parser, "checkIndent", null);
xml_parse($parser, $xml, true);
?>
Нарушение отступа в теге CHILD: столбец 3
Интеграция с логгированием

Пример записи позиций тегов в лог-файл для последующего анализа:

Пример php
<?php
$xml = file_get_contents('data.xml');
$parser = xml_parser_create();
$log = fopen('parse.log', 'w');

function logPosition($parser, $name) {
    global $log;
    $line = xml_get_current_line_number($parser);
    $column = xml_get_current_column_number($parser);
    fwrite($log, "Тег $name: строка $line, столбец $column\n");
}

xml_set_element_handler($parser, "logPosition", null);
xml_parse($parser, $xml, true);
fclose($log);
?>

Содержимое файла parse.log после выполнения:

Тег ROOT: строка 1, столбец 1
Тег ITEM: строка 2, столбец 3

PHP xml_get_current_column_number function comments

En
Xml get current column number Get current column number for an XML parser