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. Не спрашивай меня почему..

http://www.w3.org/TR/xproc/

Если вы не будете составлять содержимое вашей конфигурации динамически, а просто будете передавать содержимое фиксированных файлов, вы можете просто пройти путь к соответствующему файлу конфигурации и использовать fn:doc(), чтобы прочитать его изнутри XSLT файлы.

Я бы рекомендовал не писать файлы конфигурации на лету. Порядок выполнения в XProc может быть не таким последовательным, как вы могли бы ожидать.

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

НТН!

При условии, что ваш файл config-file.cfg является правильно сформированным XML и вы можете использовать XSLT 2,
вы можете использоватьfn:doc(), как предлагает grtjn, или

  1. перепишите свой конвейер 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>
    
  2. перепишите соответствующий раздел таблицы стилей следующим образом:
    <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

Другие вопросы по тегам