Рабочий процесс XSLT с переменным количеством исходных файлов - PullRequest
1 голос
/ 01 июня 2010

У меня есть набор файлов XML с фиксированной схемой именования по стране: report_en.xml, report_de.xml, report_fr.xml и т. Д. Теперь я хочу написать таблицу стилей XSLT, которая читает каждый из этих файлов с * XP4 * функция XPath, извлекает некоторые значения и генерирует один XML-файл со сводкой. У меня вопрос: Как я могу перебирать исходные файлы, не зная точных имен файлов, которые я буду обрабатывать?

В данный момент я планирую сгенерировать вспомогательный XML-файл, который содержит все имена файлов, и использовать вспомогательный XML-файл в моей таблице стилей для итерации. Список файлов будет создан с помощью небольшого скрипта PHP или bash. Есть ли лучшие альтернативы?

Мне известно о XProc , но сейчас я не могу уделять ему много времени. Может быть, кто-то может опубликовать решение XProc. Предпочтительно решение включает в себя этапы рабочего процесса, на которых отчеты загружаются в формате HTML и приводятся в порядок:)

Я буду использовать Saxon в качестве моего XSLT-процессора, поэтому, если я могу использовать специфичные для Saxon расширения, они также будут в порядке.

Ответы [ 2 ]

4 голосов
/ 01 июня 2010

Вы можете использовать стандартную функцию XPath 2.x collection () , , как это реализовано в Saxon 9.x

Саксонская реализация позволяет использовать шаблон поиска в аргументе string-Uri функции, поэтому вы можете указать шаблон пути для любого имени файла, начиная с report_, после пути к каталогу, а затем два других символы, заканчивающиеся на .xml.

Пример

Это выражение XPath:

collection('file:///c:/?select=report_*.xml')

выбирает узлы документа каждого XML-документа, который находится в c:\, в файле с именем, начинающимся с report_, затем имеющим 0 или более символов, а затем заканчивающимся .xml.

2 голосов
/ 11 ноября 2011

Ответ Димитра выглядит как самое быстрое решение в вашем случае.Но так как вы спросили, вот альтернатива XProc:

<p:declare-step version="1.0" xmlns:p="http://www.w3.org/ns/xproc" xmlns:c="http://www.w3.org/ns/xproc-step" exclude-inline-prefixes="#all" name="main">

<!-- create context for p:variable with base-uri pointing to the location of this file -->
<p:input port="source"><p:inline><x/></p:inline></p:input>

<!-- any params passed in from outside get passed through to p:xslt automatically! -->
<p:input port="parameters" kind="parameter"/>

<!-- configuration options for steering input and output -->
<p:option name="input-dir" select="'./'"/>
<p:option name="input-filter" select="'^report_.*\.xml$'"/>
<p:option name="output-dir" select="'./'"/>

<!-- resolve any path to base uri of this file, to make sure they are absolute -->
<p:variable name="abs-input-dir" select="resolve-uri($input-dir, base-uri(/))"/>
<p:variable name="abs-output-dir" select="resolve-uri($output-dir, base-uri(/))"/>

<!-- first step: get list of all files in input-dir -->
<p:directory-list>
    <p:with-option name="path" select="$abs-input-dir"/>
</p:directory-list>

<!-- iterate over each file to load it -->
<p:for-each>
    <p:iteration-source select="//c:file[matches(@name, $input-filter)]"/>
    <p:load>
        <p:with-option name="href" select="resolve-uri(/c:file/@name, $abs-input-dir)"/>
    </p:load>
</p:for-each>

<!-- wrap all files in a reports element to be able to hand it in to the xslt as a single input document -->
<p:wrap-sequence wrapper="reports"/>

<!-- apply the xslt (stylesheet is loaded below) -->
<p:xslt>
    <p:input port="stylesheet">
        <p:pipe step="style" port="result"/>
    </p:input>
</p:xslt>

<!-- store the result in the output dir -->
<p:store>
    <p:with-option name="href" select="resolve-uri('merged-reports.xml', $abs-output-dir)"/>
</p:store>

<!-- loading of the stylesheet.. -->
<p:load href="process-reports.xsl" name="style"/>

</p:declare-step>

Сохраните вышеупомянутое как, например, process-reports.xpl.Вы можете запустить его с XMLCalabash (http://xmlcalabash.com/download/).. Вы можете запустить его так:

java -jar calabash.jar process-reports.xpl input-dir=./ output-dir=./

. Приведенный выше код предполагает файл process-reports.xsl, который принимает один документ, который упаковывает все отчеты, и выполняетобработка на нем. Вы также можете выполнить обработку в чистом XProc, но вы можете предпочесть это следующим образом.

Вы также можете переместить шаг p: xslt вверх в пределах p: for-each (ниже p: load), что приведет к тому, что xslt будет применен к каждому отчету отдельно.

Удачи!

...