Как сделать выборку обязательных вопросов из XML анкеты по атрибуту обязательности
Что проверяют
Умеете ли вы читать структуру XML и доставать из неё данные XPath-выражением, не прибегая к ручному перебору. Следом обычно усложняют: вопросы лежат во вложенных секциях, у документа есть пространство имён или атрибут записан по-разному.
Как отвечать
Сначала уточните, как устроен документ и что считается обязательностью. Базовые выражения:
//question[@mandatory='true']: все элементыquestionна любой глубине, у которых атрибут равен строкеtrue;//section[@id='s2']/question[@mandatory='true']: только в нужной секции;//question[@mandatory='true']/@idили.../text(): вернуть идентификаторы или текст вместо узлов;count(//question[@mandatory='true']): сверить количество с ожиданием.
Дальше нюансы, которые стоит проговорить самому. Если у корня есть пространство имён xmlns="...", выражение без префикса ничего не найдёт: нужно объявить префикс в инструменте или писать //*[local-name()='question']. Значение атрибута сравнивается как строка, поэтому true, 1 и True для XPath разные вещи. Отсутствие атрибута означает значение по умолчанию из XSD, и его надо знать заранее.
Инструменты зависят от задачи: XPath-тестер в XML-редакторе или плагине IDE, ассерты в SoapUI, в Python библиотека lxml с полноценным XPath. Если анкеты лежат в базе, в PostgreSQL их разворачивает в строки XMLTABLE, в SQL Server методы .nodes() и .value().
Полезно разделить два понятия. Бизнес-признак «вопрос обязателен к ответу» это атрибут в данных, а use="required" и minOccurs="1" в XSD говорят только о том, что элемент или атрибут должен присутствовать в документе.
Где спотыкаются
Пишут путь только по прямым потомкам, например survey/question. Вопросы во вложенных секциях теряются.
Проверяют наличие атрибута через [@mandatory]. Вопрос с mandatory="false" тоже попадёт в выборку.
Забывают про пространство имён и тратят время на выражение, которое формально верно, но возвращает пустой результат.