Форматы результата
Как устроен результат в JSON, XML и CSV/XLSX: имена полей, массивы и развёртка вложенных объектов.
Формат результата — json, xml, csv или xlsx — задаётся по умолчанию у типизатора и может
быть переопределён на отдельный прогон (format в POST /v1/extract или POST /v1/typizers/{id}/runs). Готовый результат в выбранном формате отдаёт GET /v1/runs/{id}/output?format=… (по умолчанию — формат самого прогона) как файл для скачивания
(Content-Disposition: attachment; filename="<id прогона>.<расширение>"); XML, CSV и XLSX во всех
случаях построены по порядку полей properties в схеме, а не по порядку ключей в output.
JSON: output и fields
output — объект той же формы, что и схема: ключи — имена полей из properties (вложенные объекты
и массивы — как есть, без развёртки). Поле схемы, для которого в документе ничего не нашлось, —
null, а не отсутствующий ключ.
fields — отдельный объект результата, с одной записью на каждое конечное поле схемы (путь вида
seller.inn или items[0].amount — без контейнеров вроде items, если сам контейнер не null):
{
"status": "ok",
"reason": "checksum_mismatch",
"sources": [{ "page": 1, "bbox": [0.12, 0.34, 0.2, 0.36], "text": "7707083893" }]
}status—ok,warnилиmissing;reasonприсутствует только приwarn;sources— места в документе, откуда взято значение:page(с 1),bbox— рамка[x0, y0, x1, y1]в долях страницы от левого верхнего угла (илиnull, если положение не определено),text— исходный текст. Список пуст, если источник не определён (в том числе дляmissing).
Что означают статусы и причины warn — «Проверки полей». fields и
output есть только у успешного прогона; у неуспешного — код ошибки в run.error.
XML: имена, массивы, XSD
GET /v1/runs/{id}/output?format=xml рендерит output в XML по схеме, которой выполнен прогон:
- корневой элемент — всегда
<document>; - каждое поле
properties— элемент с тем же именем, в порядке объявления в схеме (не в порядке ключейoutput); поле, которого нет вoutputвовсе, просто не попадает в XML; null— пустой элемент сxsi:nil="true"(<phone xsi:nil="true"/>) — это не то же самое, что отсутствующее поле;- массив (
items) — элемент-обёртка с тем же именем поля, внутри — один<item>на каждый элемент массива, в порядке самого массива (единственный случай, где порядокoutput, а не схемы, имеет значение — у массива нет своего «порядка схемы»); - значение, которое выходит за пределы простого текста (число, строка, булево), становится текстом элемента; число сериализуется без экспоненциальной записи, при любой величине.
Соответствующую XSD-схему для типизатора отдаёт GET /v1/typizers/{id}/xsd — тот же корень
<document>, с xs:complexType/xs:sequence по тем же properties, в том же порядке. Каждый
элемент — minOccurs="0" nillable="true" (XML не навязывает required схемы); элемент массива
дополнительно несёт maxOccurs="unbounded" на своём <item>. Поле с format: "date" или
"date-time" получает тип xs:date/xs:dateTime, поле с enum — ограничение xs:restriction по
перечисленным значениям, остальные — xs:integer/xs:decimal/xs:boolean/xs:string по типу
поля.
CSV/XLSX: развёртка через точку, массивы на отдельный лист (файл)
CSV и XLSX — табличные форматы, поэтому вложенность схемы разворачивается в отдельные таблицы:
- основная таблица (
data) — одна строка на прогон:run_idи по одной колонке на каждое вложенное не-массивное поле, с именем-путём через точку (seller.inn,items[].amountв основную таблицу не попадает — у него своя таблица, см. ниже); - на каждое поле-массив — отдельная таблица (CSV: отдельный файл; XLSX: отдельный лист), с
именем — полным путём поля через точку (
items,items.discountsи т. д.); колонки —run_id,index(номер элемента с 1) и дальше:- если элемент массива — объект, его собственные не-массивные поля тем же способом через точку;
- если элемент массива — не объект (строка, число), единственная колонка
value;
- массив внутри элемента другого массива отдельной таблицы не получает (у такой вложенной строки нет третьего ключа, которым можно связать её с родителем) — он попадает в одну ячейку родительской строки как JSON-текст.
Для CSV: один прогон без полей-массивов — один файл data.csv; если поля-массивы есть — zip из
data.csv и по одному <путь>.csv на каждый из них. Для XLSX — всегда одна книга, один лист
data плюс один лист на поле-массив (имя листа — тот же путь, обрезанный до 31 символа по
ограничению Excel, с ~2, ~3… при совпадении). Выгрузка в XLSX с таблицей больше 1 048 575
строк отклоняется (413 file_too_large) — лист Excel не вмещает больше.
Защита от CSV/формул-инъекций. Значения в документе извлекает модель, поэтому строка может
случайно или намеренно начинаться с =, +, -, @, табуляции или перевода строки — именно
так Excel и Google Таблицы опознают формулу в ячейке. И в CSV, и в XLSX такая строка записывается
с ведущим ' (апостроф), который открывает её как обычный текст, а не как формулу — апостроф
остаётся видимым при открытии файла.
Что дальше
- «Поддерживаемый JSON Schema» — какие поля и ключевые слова допустимы в схеме.
- «Проверки полей» — статусы
ok/warn/missingи их причины. - «Пакетная обработка» — та же развёртка для
GET /v1/batches/{id}/export, несколько прогонов в одних и тех же таблицах. GET /v1/runs/{id}/outputв «Справочнике API» — параметры, заголовки ответа и примеры запроса на каждом языке.