Посты с тэгом «xslt»

  • XSL Tracer

    Я, наконец-то, более-менее довёл до ума свой новый проект, которым хочу поделиться с народом.

    Проект называется XSL Tracer. Его задача заключается в том, чтобы ответить на простой вопрос: откуда после XSL-трансформации пришёл тот или иной элемент? Как это работает можно увидеть на демо-странице. Там отображается результат XSL-преобразования — обычный HTML-документ. Кликнув по любому элементу можно получить подробную информацию о нём:

    • XSL: шаблон, где выводится элемент.
    • Context: контекстный XML (на который сработал матч, в случае xsl:apply-templates). Сам элемент выводится урезанным (только 10 внутренних тэгов), чтобы в случае, если это будет корневой элемент, браузер не умер в муках (да и толку от полной структуры никакого).
    • Source: место в шаблоне, где непосредственно генерируется выбранный элемент. Очень удобно в случае, если делаете сopy-of результатирующей структуры (в примере это html-код, заданный внтутри переменной).
    • Call stack: стэк вызовов apply-template/call-template/apply-imports, через который дошли до вызова текущего шаблона
    • Inner calls: список внутренних вызовов шаблонов, которые по каким-то причинам нельзя отобразить (по крайней мере пока) в документе. Например, вызов шаблонов, выдающих атрибуты для выбранного элемента, или его текстовое содержимое. Список отображается под Call stack, и только в том случае, если такие вызовы есть.

    Демка нормально работает в Safari/Firefox/Chrome, Opera жутко тормозит на больших документах, а в IE даже не открывал.

    Везде, где это возможно, выводится xpath к выбранному элементу, который можно скопировать одним кликом, имена файлов и номер строки, чтобы можно было легко найти нужный шаблон в редакторе.

    Как это работает

    Проект состоит из двух частей: бэкэнд и фронтэнд.

    На бэкэнде используется Saxon 6.5 (пока эта версия, так как в 9.2 лично у меня вылезло куча проблем с EXSLT). У него есть встроенный механизм трассировки, который по умолчанию генерирует результат в виде XML (такой файл на реальных проектах вырастает до нескольких мегабайт). Я написал свой трассировочный класс, который выводит данные в более компактном и лёгком JSON-формате, а также дополнительные данные вроде списка используемых в трансформации XSL и XML (подключённых через document()) документов. А также он делает дополнительные штуки вроде резолвинга result-tree фрагментов при вызове xsl:copy-of.

    Этот трассировщик генерирует JSON-документ и результатирующий документ (то есть результат предобразования) и собирает их в одном HTML-файле, который можно открывать в браузере.

    Дальше за работу берётся фронтэнд, который связывает трассировочные данные с результатом трансформа и обеспечивает всю работу интерфейса.

    Как запускать

    1. Должна быть установлена Java (версия особо не важна).
    2. Скачиваем Saxon 6.5
    3. Скачиваем трэйсер
    4. Генерируем трассировку вот такой командой в консоли:

    java -classpath /path/to/tracer.jar:/path/to/saxon.jar ru.imobilco.XSLTracer -to /path/to/trace-result.html /path/to/input.xml /path/to/template.xsl

    В случае успешной работы трэйсера сгенерируется файл trace-result.html, который можно сразу открывать в браузере (CSS и JS берутся с моего сервера). Если возникла ошибка во время трансформа, то файл будет сгенерирован, но вместо документа увидите нормальное сообщение об ошибке. В случае ошибки работы Java, увидите сообщение в консоли.

    Надо помнить, что Saxon очень чувствителен ко всяким всяким отхождениям от спецификации, поэтому то, что работало в Xalan/libxsl/где-то ещё может не сработать в Saxon. Но исправления, как правило, довольно мелкие и незначительные.

    Онлайн-версия

    Мой коллега Лёха Баранов написал сервлет, который позволяет запускать через веб, передавая ссылки на XML и XSL файлы. Для него был заведён специальный проект xmltools.ru. Работает просто: указываете ссылки на файлы и, если нужно, данные для http-авторизации. Далее сам трансформ находит все зависимые файлы, скачивает их и делает трансформ.

    Но с онлайн-версией не так всё просто. В частности, когда результат отдаётся фронтэнду, он тоже начинает скачивать внешние файлы через аякс. И, как вы уже, наверно, догадались, включается ограничение Same-Origin Policy, которое не позволяет загружать данные с другого домена. Вариантов решения два: либо вы свой сервер настраиваете на cross-domain ajax, либо используете xmltools.ru как сервис, запрашивая трансформ через какой-нибудь php/python/ruby скрипт, отдавая результат трассировки со своего домена.

    Онлайн-версия пока находится в состоянии «альфа», поэтому может быть много багов. И пока бесплатна. Подчёркиваю, пока бесплатна. Дело в том, что такие трассировки генерируют очень большую нагрузку, и если она возрастёт до каких-то критических значений, то придётся прикрыть лавочку и предоставлять услугу на коммерческой основе.

    Метки: , , ,