Здравствуйте. Прошу простить, получилось много текста, надеюсь легко читаемого наискосок. Короче выразиться не получилось. :)
Помогите, пожалуйста, выбрать решение. Попытался поискать похожие проблемы, но как ограничить область поиска не придумал: xsl xmlns версия... Результатов куча, всё не то.
Задача: выполнить преобразование через xsl, чтобы загрузить документ в свою структуру (свою БД). На входе — файл xml-документа, соответствующий чужой схеме. Эта схема время от времени дорабатывается (вслед за бизнес-требованиями к структуре документа), то есть имеют хождение документы с разными версиями структуры. Для всех версий известны xsd.
Особенность в том, что одни и те же пространства имён в разных версиях схемы идентифицируются разными URI. То есть в URI входит номер версии, причём у каждого пространства имён нумерация своя. Например, в документе заголовок корневого узла выглядит так:
<SomeDoc1
xmlns="urn:site.ru:SomeDoc1:1.0"
xmlns:aaa="urn:site.ru:SomeSimple:1.0"
xmlns:bbb="urn:site.ru:SomeComplex:1.0">
а в другом документе, где структура документа в чём-то отличается, он выглядит иначе:
<SomeDoc1
xmlns="urn:site.ru:SomeDoc1:1.1"
xmlns:aaa="urn:site.ru:SomeSimple:1.2"
xmlns:bbb="urn:site.ru:SomeComplex:2.0">
И тот и другой (и ещё другие варианты) документ отвечает соответствующей xsd, все они имеются. То есть речь НЕ идёт обо всех возможных комбинациях цифр. Структура первого примера опубликована как "версия формата 1", второго — "версия формата 2". Всего таких "версий формата" не много, но время от времени публикуются новые.
Заранее неизвестно какая версия на этот раз в пришедшем файле.
Надеюсь, что кто-то сталкивался с такой организацией версий схем, или это какой-то общеизвестный способ, имеющий название, и кучу наработок по поддержке xsl :) Направьте меня, если так.
Проблема в том, чтобы автоматически выбиралось подходящее преобразование. Способов видится несколько.
1. Иметь копии xsl для каждой версии формата (они будут мало отличаться, схема большая, изменения невелики), и перед запуском преобразования открывать вместе с каждым из них входной документ, чтобы сопоставить каждый namespace. Это решение, кажется, ясно, но есть другое (?).
2. Придумал в одном файле преобразования объявлять сразу несколько версий, и дублировать элементы преобразования для каждой версии. Надеялся на выигрыш в том, что автоматически сработают только соответствующие входной версии элементы.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:SomeDoc1_1.0="urn:site.ru:SomeDoc1:1.0"
xmlns:aaa_1.0 ="urn:site.ru:SomeDoc1:1.0"
xmlns:bbb_1.0 ="urn:site.ru:SomeComplex:1.0"
xmlns:SomeDoc1_1.1="urn:site.ru:SomeDoc1:1.1"
xmlns:aaa_1.2 ="urn:site.ru:SomeDoc1:1.2"
xmlns:bbb_2.0 ="urn:site.ru:SomeComplex:2.0"
>
<MyField1>
<xsl:value-of select="SomeDoc1_1.0:Address/bbb_1.0:Street/aaa_1.0:Name"/>
<xsl:value-of select="SomeDoc1_1.1:Address/bbb_2.0:Street/aaa_1.2:Name"/>
</MyField1>
Но в таком виде это не работает, во входном документе всегда отсутвуют другие версии пространств имён, кроме одной, той, в которой документ написан. Ошибка указывает на первую же отсутвующую:
XSLT 1.0 Debugging Error: Invalid prefixError in XPath expression, Invalid prefix
Как реализовать такое преобразование? Или, возможно, не стоит так делать, если это хоженые грабли :)