Я искал этот вопрос, но кажется, как ни странно трудно выразить проблему, касающуюся XSL, в словах, поэтому я ничего не придумал.
Проблема, с которой я столкнулся, такова:
Компания производит приложение, которое использует XML-файлы для хранения своих «документов». Эти файлы применяются к схеме версии 1.1
Однако компания решает выпустить новую версию программного обеспечения, которая проверяет соответствие новой схеме с другой структурой, схемой 1.2
.
Чтобы клиент мог беспрепятственно использовать новую версию, мы хотим программно преобразовать свои 1.1-совместимые файлы в 1.2-совместимость при открытии файла. В идеале мы делаем это с помощью XSL-преобразования.
Из двух схем некоторые типы идентичны, некоторые имеют новые или переименованные элементы, а некоторые хранятся в совершенно другой структуре. Поэтому написание преобразования из одного в другое довольно утомительно, и поддерживать его тем более.
Было бы неплохо написать некое преобразование, генерирующее преобразование, которое может сопоставлять неизмененные типы из старой схемы с новой и генерировать элементы-заполнители (например, элементы <xsl:message>
) везде, где это невозможно. поэтому, чтобы побудить разработчика написать собственную логику от руки там, где это необходимо, с гарантией того, что все остальное является совместимым.
Итак, процедура идет:
- Запустить преобразование A против схемы 1.2. Это генерирует Transform B;
- Запустите Transform B против схемы 1.1. Это соответствует Схеме 1.2 и Схеме 1.1, где это возможно, создавая Преобразование C;
- Преобразование C используется разработчиком в качестве каркаса для записи водонепроницаемого преобразования из экземпляр 1.1 в экземпляр 1.2 .
Я реализовал честный способ реализации этого, но некоторые особенности XSLT 1.0 вызывают у меня проблемы.
Преобразование B требует автоматической генерации операторов <xsl:call-template>
с именем типа каждого найденного элемента, вписанным в атрибут name
. Затем он будет правильно запускать логику преобразования для каждого типа , чтобы сгенерировать преобразование C.
Однако call-template
, похоже, не принимает какой-либо синтаксис xpath. Он настаивает на том, что name
должен содержать только NMTOKEN и NMTOKEN. Я могу понять это с точки зрения дизайна, но это довольно раздражает, потому что я хочу запускать логику для элемента на основе его типа, а не его имени. Я хотел бы указать call-template name="@type"
внутри xsl:template match="element"
шаблона. Мое поколение 1-го этапа гарантирует, что соответствующий именованный шаблон будет существовать для вызова.
Я не уверен, как поступить. Кто-нибудь пробовал что-то подобное раньше? Есть ли фундаментальная теория информатики, которая заявляет, что это невозможно в декларативном синтаксисе? (Надеюсь нет!)
Надеюсь, мое объяснение понятно. Я отправлю код, если нет.