XSLT с XProc - привязка параметров в требуемом типе
Я пытаюсь перевести мой пакетный файл, называющий Saxon (версия 8.9), в конвейер XProc (Calabash). Это мой пакетный звонок:
java -jar saxon8.jar -o out.xml in.xml style.xsl +config=config-file.cfg
Параметр config определяется в таблице стилей следующим образом:
<xsl:param name="config" as="document-node()"/>
Часть XProc выглядит так:
<p:load name="configLoad">
<p:with-option name="href" select="'config-file.cfg'"/>
</p:load>
<p:xslt name="config">
<p:input port="source">
<p:document href="in.xml"/>
</p:input>
<p:input port="parameters">
<p:inline>
<c:param name="config">
<p:pipe port="result" step="configLoad"/>
</c:param>
</p:inline>
</p:input>
<p:input port="stylesheet">
<p:document href="style.xsl"/>
</p:input>
</p:xslt>
Сообщение об ошибке таково:
Обязательный тип элемента значения переменной $config - document-node(); предоставленное значение имеет тип элемента xs:string
Я знаю <p:exec>
шаг, но я не хочу его использовать, потому что файл конфигурации должен быть сгенерирован другими преобразованиями XSLT позже. Он также должен быть использован другими этапами XProc.
Есть ли возможность вызвать таблицу стилей XSLT с правильным типом параметра? Спасибо за вашу помощь!
1 ответ
Похоже, вам не повезло с текущим стандартом XProc. В нем говорится, что параметры - это пары имя / значение, где тип данных значений должен быть строкой untypedAtomic. Не спрашивай меня почему..
Если вы не будете составлять содержимое вашей конфигурации динамически, а просто будете передавать содержимое фиксированных файлов, вы можете просто пройти путь к соответствующему файлу конфигурации и использовать fn:doc(), чтобы прочитать его изнутри XSLT файлы.
Я бы рекомендовал не писать файлы конфигурации на лету. Порядок выполнения в XProc может быть не таким последовательным, как вы могли бы ожидать.
Альтернативой может быть пропуск каждого параметра конфигурации в качестве отдельного параметра, но тогда каждый параметр все равно должен соответствовать типу значения плоского параметра.
НТН!
При условии, что ваш файл config-file.cfg является правильно сформированным XML и вы можете использовать XSLT 2,
вы можете использоватьfn:doc()
, как предлагает grtjn, или
- перепишите свой конвейер XProc следующим образом:
<p:load name="configLoad"> <p:with-option name="href" select="'config-file.cfg'"/> </p:load> <p:xslt name="config" version="2.0"> <p:input port="source"> <p:document href="in.xml"/> <p:pipe port="result" step="configLoad"/> </p:input> <p:input port="parameters"> <p:empty/> </p:input> <p:input port="stylesheet"> <p:document href="style.xsl"/> </p:input> </p:xslt>
- перепишите соответствующий раздел таблицы стилей следующим образом:
<xsl:param name="config" as="document-node()" select="subsequence(collection(), 2)"/>
Это позволяет получить доступ к вторичному входному документу из коллекции xslt по умолчанию.
Обратите внимание, что промежуточных<p:store>
шаг нужен.
Кроме того, если вы не планируете повторно использовать загруженный документ config-file.cfg на других этапах, вам даже не понадобится<p:load>
внутри вашего конвейера: вы можете просто использовать <p:document>
внутри входного порта источника, например:
<p:input port="source">
<p:document href="in.xml"/>
<p:document href="config-file.cfg"/>
</p:input>
Я протестировал это в Oxygen XML, и он работает.
Кстати, вся заслуга в этом ответе принадлежит Мартину Хоннену, см. Здесь: /questions/28926172/peredacha-parametra-document-v-xslt-v-konvejere-xproc/55460397#55460397