Необходимые cookie-файлы нужны для работы сайта. Аналитические cookie (Яндекс Метрика) — только с вашего согласия. Политика cookie-файлов

Тема оформления
Справочник

Форматы результата

Как устроен результат в 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):

JSON
{
  "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 такая строка записывается с ведущим ' (апостроф), который открывает её как обычный текст, а не как формулу — апостроф остаётся видимым при открытии файла.

Что дальше