XmlParser
Низкоуровневое последовательное чтение XML-элементов из UTF-8 ввода.
Откройте файл или буфер и проверяйте результат каждого Read. Error.FileEof завершает чтение. Реальные имена методов SDK — GetNodeType/GetNodeName: Node здесь означает элемент XML, а не игровую Entity.
Это не строгий валидатор XML, DOM, схема или автоматическое разрешение пространств имён. Читатель может пройти несовпадающие закрывающие теги без ошибки. Успешное чтение не заменяет проверку структуры и полей вашего формата.
В текущем ридере короткий пробельный хвост может вернуть Error.Ok с прежними типом и атрибутами. Поэтому пример ниже проверяет начало текущего шага в исходном буфере и не добавляет повторный элемент.
Пример собирает значения атрибута у элементов с точным именем на любой глубине. Отсутствующий атрибут пропускается, существующий пустой включается. Это извлечение, не проверка всего документа. Передавайте System.Text.Encoding.UTF8.GetBytes(text) и сохраняйте входной массив неизменным во время вызова.
using System;
using System.Collections.Generic;
using Reckfell;
public static class XmlAttributeExample
{
public static Error Collect(byte[] utf8, string elementName, string attributeName,
out string[] values)
{
values = Array.Empty<string>();
if (utf8.Length == 0)
return Error.InvalidData;
using var parser = new XmlParser();
Error error = parser.OpenBuffer(utf8);
if (error != Error.Ok)
return error;
var found = new List<string>();
while (true)
{
error = parser.Read();
if (error == Error.FileEof)
{
values = found.ToArray();
return Error.Ok;
}
if (error != Error.Ok)
return error;
if (parser.GetNodeType() == XmlParser.NodeType.Element
&& parser.GetNodeName() == elementName
&& parser.HasAttribute(attributeName))
{
// A short whitespace-only read can retain the preceding token.
int start = (int)parser.GetNodeOffset();
while (start < utf8.Length && utf8[start] is 9 or 10 or 13 or 32)
start++;
if (start < utf8.Length && utf8[start] == (byte)'<')
found.Add(parser.GetNamedAttributeValue(attributeName));
}
}
}
}Смещения XmlParser — байты UTF-8; не подставляйте их в C# Substring. Seek уже читает элемент, SkipSection меняет текущую позицию, поля после EOF могут остаться от прошлого чтения.
Объявления сверены с C# SDK 1.0.0. Раскройте имя, чтобы увидеть сигнатуры и описание.
Конструкторы1
XmlParserКонструктор
public XmlParser();Создаёт низкоуровневый читатель без открытого ввода и текущего элемента. Сначала Open/OpenBuffer, затем Read и проверка Error. Это не DOM и не проверка схемы XML.
Методы18
GetAttributeCountint
public int GetAttributeCount();Читает размер текущего списка атрибутов. Сначала проверьте GetNodeType()==Element: на Text/Comment могут оставаться атрибуты предыдущего элемента. Закрывающий тег очищает список.
intРазмер списка атрибутов; вне Element он может быть устаревшим.
GetAttributeNamestring
public string GetAttributeName(int idx);Читает имя атрибута по индексу текущего списка. Используйте на Element после проверки диапазона, а не на текстовом элементе с оставшимися старыми атрибутами.
| Имя | Тип | По умолчанию |
|---|---|---|
idx | int | — |
idxИндекс 0 <= idx < GetAttributeCount() у текущего Element. Неверный индекс вызывает нативную диагностику с пустым результатом.
stringСтрока из текущего списка атрибутов. Наличие и допустимость индекса/имени проверяйте отдельно.
GetAttributeValuestring
public string GetAttributeValue(int idx);Читает строковое значение атрибута по индексу. Поддерживаемые ссылки на символы уже раскрыты; например a&b читается как a&b. Это не автоматическое преобразование к числу.
| Имя | Тип | По умолчанию |
|---|---|---|
idx | int | — |
idxИндекс 0 <= idx < GetAttributeCount() у текущего Element. Неверный индекс вызывает нативную диагностику с пустым результатом.
stringСтрока из текущего списка атрибутов. Наличие и допустимость индекса/имени проверяйте отдельно.
GetCurrentLineint
public int GetCurrentLine();Возвращает текущий счётчик прочитанных LF (\n) с нуля. Seek не пересчитывает его для новой позиции, поэтому после произвольных переходов это не надёжный номер строки целевого элемента.
intТекущий счётчик строк с нуля; после Seek может не соответствовать позиции.
GetNamedAttributeValuestring
public string GetNamedAttributeValue(string name);Читает атрибут по точному имени. Если его нет, выводит нативную ошибку и возвращает пустую строку; не полагайтесь на исключение C#. Для необязательного поля сначала используйте HasAttribute или безопасный getter.
| Имя | Тип | По умолчанию |
|---|---|---|
name | string | — |
nameТочное имя атрибута с учётом регистра. Префикс пространства имён остаётся частью текстового имени, не заменяйте его автоматически.
stringСтрока из текущего списка атрибутов. Наличие и допустимость индекса/имени проверяйте отдельно.
GetNamedAttributeValueSafestring
public string GetNamedAttributeValueSafe(string name);Читает атрибут по точному имени без диагностики отсутствия. Пустой результат означает как отсутствующий атрибут, так и существующее пустое значение; различайте через HasAttribute.
| Имя | Тип | По умолчанию |
|---|---|---|
name | string | — |
nameТочное имя атрибута с учётом регистра. Префикс пространства имён остаётся частью текстового имени, не заменяйте его автоматически.
stringСтрока из текущего списка атрибутов. Наличие и допустимость индекса/имени проверяйте отдельно.
GetNodeDatastring
public string GetNodeData();Читает содержимое только текущего Text-элемента, включая обработку поддерживаемых ссылок на символы. Для Comment/Cdata используйте GetNodeName. Неверный тип элемента вызывает нативную ошибку, не гарантированное исключение C#.
stringТекст текущего Text-элемента. Для другого типа возможны диагностика и пустая строка.
GetNodeNamestring
public string GetNodeName();Для Element/ElementEnd читает имя тега; для Comment/Cdata возвращает содержимое комментария/CDATA. Для Text нужен GetNodeData: GetNodeName на текстовом элементе является ошибкой нативного API.
stringИмя тега либо содержимое Comment/Cdata по типу текущего элемента.
GetNodeOffsetulong
public ulong GetNodeOffset();Возвращает байтовое смещение начала текущего шага разбора в исходном UTF-8 буфере. Это не индекс C# строки и не количество Unicode-символов. При пропуске короткого пробельного текста шаг может начинаться до символа <. Сохранённое смещение применимо к тому же неизменённому вводу.
ulongСмещение в байтах исходного UTF-8 ввода. Не длина элемента.
GetNodeTypeXmlParser.NodeType
public XmlParser.NodeType GetNodeType();Возвращает сохранённый тип текущего XML-элемента потока. Проверяйте Error чтения и ограничение Read на коротком пробельном хвосте: прежний тип может сохраниться даже после Ok. Имена NodeType относятся к XML, а не к игровой иерархии Entity.
XmlParser.NodeTypeТекущее значение XmlParser.NodeType; сначала проверьте Error чтения.
HasAttributebool
public bool HasAttribute(string name);Проверяет наличие точного имени атрибута в текущем списке, с учётом регистра. Используйте на Element; отсутствие и существующий атрибут с пустым значением — разные случаи.
| Имя | Тип | По умолчанию |
|---|---|---|
name | string | — |
nameТочное имя атрибута с учётом регистра. Префикс пространства имён остаётся частью текстового имени, не заменяйте его автоматически.
booltrue при наличии точного имени, включая атрибут с пустым значением.
IsEmptybool
public bool IsEmpty();Для текущего Element сообщает о самозакрывающейся записи вроде <item/>. Это не признак конца файла или пустоты всего документа. Такой элемент не создаёт отдельный ElementEnd. На других типах не используйте этот флаг как проверку структуры.
booltrue для самозакрывающегося Element; не состояние всего документа.
OpenError
public Error Open(string file);Читает файл в собственный буфер для последующего Read. Успех открытия не разбирает первый элемент и не подтверждает корректность всего XML. Проверяйте Error до чтения; файл загружается в память, а не читается порциями с диска на каждом Read.
| Имя | Тип | По умолчанию |
|---|---|---|
file | string | — |
fileПуть файла через FileAccess: asset://, user:// или доступный абсолютный путь. Это не строка XML.
ErrorError.Ok при подготовленном вводе; иначе код отказа. Успех не является проверкой всего XML.
OpenBuffer2 перегрузки
public Error OpenBuffer(byte[] buffer);Копирует входные байты в собственный буфер и ставит курсор в начало. Данные передавайте в UTF-8; это не автоматическое распознавание всех кодировок XML. Первый элемент читается отдельным Read. При повторном открытии не используйте прежние поля текущего элемента до успешного Read.
| Имя | Тип | По умолчанию |
|---|---|---|
buffer | byte[] | — |
bufferНепустые байты UTF-8, например Encoding.UTF8.GetBytes(text). Открытие копирует их; изменение исходного массива после возврата не меняет ввод читателя.
ErrorError.Ok при подготовленном вводе; иначе код отказа. Успех не является проверкой всего XML.
public Error OpenBuffer(ReadOnlySpan<byte> buffer);Копирует входные байты в собственный буфер и ставит курсор в начало. Данные передавайте в UTF-8; это не автоматическое распознавание всех кодировок XML. Первый элемент читается отдельным Read. При повторном открытии не используйте прежние поля текущего элемента до успешного Read.
| Имя | Тип | По умолчанию |
|---|---|---|
buffer | ReadOnlySpan<byte> | — |
bufferНепустые байты UTF-8, например Encoding.UTF8.GetBytes(text). Открытие копирует их; изменение исходного массива после возврата не меняет ввод читателя.
ErrorError.Ok при подготовленном вводе; иначе код отказа. Успех не является проверкой всего XML.
ReadError
public Error Read();Выполняет следующий шаг чтения. Проверяйте Error, но учитывайте ограничение текущей реализации: короткий пробельный хвост может дать Error.Ok с прежними типом, именем и атрибутами. Пример в описании класса проверяет байты текущего шага, чтобы не повторять элемент. FileEof тоже не очищает прежний результат. Читатель не проверяет полную корректность XML.
ErrorError.Ok после шага либо Error.FileEof при окончании. Ok не всегда означает новый токен на коротком пробельном хвосте; EOF не доказывает структурную корректность XML.
SeekError
public Error Seek(ulong position);Перемещает курсор к байтовому смещению и сразу выполняет Read. После Error.Ok текущий элемент уже прочитан: дополнительный Read перейдёт дальше. Счётчик строки не восстанавливается по позиции. Предпочитайте смещение, ранее полученное из этого же буфера.
| Имя | Тип | По умолчанию |
|---|---|---|
position | ulong | — |
positionБайтовое смещение от начала текущего ввода, не индекс UTF-16 и не номер строки. Значение должно указывать внутрь того же буфера.
ErrorРезультат Read на новой позиции; при недоступном/внешнем смещении возможен FileEof с диагностикой.
SkipSectionvoid
public void SkipSection();Вызывайте на открывающем Element. Для самозакрывающегося элемента ничего не читает. Для непустого читает вложенные элементы до закрывающего по счётчику вложенности или EOF; остаётся на закрывающем элементе. Следующий Read перейдёт за раздел. Имена тегов и схема не проверяются.
XmlParser.NodeType
| Значение | Описание |
|---|---|
Cdata = 5 | Тип узла для разделов CDATA (символьные данные), например, |
Comment = 4 | Тип узла комментария, например, |
Element = 1 | Тип узла элемента, также известный как тег, например, |
ElementEnd = 2 | Конец типа узла элемента, например |
None = 0 | Нет узла (файл или буфер не открыты). |
Text = 3 | Тип текстового узла, т.е. текст, который не находится внутри элемента. Сюда входят пробелы. |
Unknown = 6 | Неизвестный тип узла. |