Я искал этот вопрос, но кажется чертовски сложно выразить словами проблему, связанную с XSL, поэтому я ничего не придумал.
Проблема у меня такая:
Компания создает приложение, которое использует XML-файлы для хранения своих «документов». Эти файлы применяются к схеме версии 1.1.
Однако компания решает выпустить новую версию программного обеспечения, которая проверяется на соответствие новой схеме с другой структурой, схеме 1.2.
Чтобы клиент мог беспрепятственно использовать новую версию, мы хотим программно преобразовать их файлы, соответствующие версии 1.1, в файлы, соответствующие версии 1.2, при открытии файла. В идеале мы делаем это с помощью XSL-преобразования.
Из двух схем некоторые типы идентичны, некоторые имеют новые или переименованные элементы, а некоторые хранятся в совершенно другой структуре. Поэтому писать преобразование от одного к другому довольно утомительно, а поддерживать его тем более.
Было бы неплохо написать своего рода преобразование, генерирующее преобразование, которое могло бы сопоставлять неизмененные типы из старой схемы в новую и испускать элементы-заполнители (элементы <xsl:message>, например) везде, где это невозможно, чтобы предложите разработчику написать пользовательскую логику вручную там, где это необходимо, с гарантией того, что везде она будет совместима.
Итак, процедура проходит:
- Запустите Transform A для схемы 1.2. Это генерирует Transform B;
- Запустите Transform B против схемы 1.1. Это соответствует схеме 1.2 схеме 1.1, где это возможно, создавая Transform 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 гарантирует, что соответствующий именованный шаблон будет существовать для вызова.
Я не уверен, что делать дальше. Кто-нибудь пробовал что-то подобное раньше? Есть ли какая-то фундаментальная теория информатики, которая заявляет, что это невозможно в декларативном синтаксисе? (Надеюсь нет!)
Надеюсь, мое объяснение понятно. Я отправлю код, если нет.
namespace-alias, но ее полезность не была сразу ясна, поэтому я проигнорировал ее. Однако это может пригодиться для решения некоторых конкретных задач. - person Tom W   schedule 18.02.2011