2015-07-07 5 views
0

Я хотел бы повторить субпиксельную часть XProc для заданного количества раз. (В моем USECASE subpipeline состоит из ехеса шага, который работает LaTeX над ранее созданным .tex-файлом)XProc - Как повторить субпипелин за определенное количество раз

упрощенной версия моего кода выглядит следующим образом, что не дает никакого результата до сих пор:

<p:declare-step version="1.0" 
xmlns:p="http://www.w3.org/ns/xproc" 
xmlns:c="http://www.w3.org/ns/xproc-step"> 

<p:option name="latex-exec" select="'uri/latex'"/> 
<p:option name="latex-repeat" select="3"/> 
<p:option name="tmp-path" select="'uri/tmp/'"/> 
<p:option name="tmp-file" select="'tmp'"/> 

<!-- pre-processing --> 

<p:for-each> 
    <p:iteration-source select="(1 to $latex-repeat)"/> 

    <p:exec result-is-xml="false"> 
     <p:with-option name="command" select="$latex-exec"/> 
     <p:with-option name="args" select="string-join(('-interaction=nonstopmode','-halt-on-error','-output-format=pdf',concat('-output-directory=',$tmp-path),concat($tmp-path,$tmp-file,'.tex')),' ')"/> 
     <p:input port="source"> 
      <p:empty/> 
     </p:input> 
    </p:exec> 
</p:for-each> 

Я не знаю, если это проблема с выражением XPath-2.0 в р: итерация исходным элементом. Однако следующие работы и дает правильный результат «сообщение: 3»:

<cx:message> 
    <p:with-option name="message" select="count((1 to $latex-repeat))"/> 
    <p:input port="source"> 
     <p:empty/> 
    </p:input> 
</cx:message> 

Мой Exec шаг проверяется вне для-каждого цикла и работ. Я работаю с Calabash под Oxygen 16.0.

ответ

0

Проблема с вашим подходом заключается в том, что вы можете перебирать только XML-документы в XProc 1.0. Поскольку select выражение в вашем p:iteration-source производит последовательность чисел, а не документов, трубопровод будет выпадать с динамической ошибки (скорее всего err:XD0001: It is a dynamic error if a non-XML resource is produced on a step output or arrives on a step input.)

(Причина, почему пример с cx:message работ является то, что p:with-option конструкция связывает значение в качестве опции, а результат выражения в select XPath затем обрабатывают, как xs:untypedAtomic.)

для цикла п количество раз, вам придется использовать рекурсию, как в следующем примере (непроверенные, но вы должны получить идея):

<p:declare-step version="1.0" 
       xmlns:p="http://www.w3.org/ns/xproc" 
       xmlns:c="http://www.w3.org/ns/xproc-step" 
       xmlns:my="http://example.org/latex-process" 
       type="my:latex-process"> 

    <p:option name="latex-exec" select="'uri/latex'"/> 
    <p:option name="latex-repeat" select="3"/> 
    <p:option name="tmp-path" select="'uri/tmp/'"/> 
    <p:option name="tmp-file" select="'tmp'"/> 

    <p:choose> 
    <p:when test="$latex-repeat = 0"> 
     <p:sink> 
     <p:input port="source"> 
      <p:empty/> 
     </p:input> 
     </p:sink> 
    </p:when> 
    <p:otherwise> 
     <p:exec result-is-xml="false"> 
     <p:with-option name="command" select="$latex-exec"/> 
     <p:with-option name="args" select="string-join(('-interaction=nonstopmode','-halt-on-error','-output-format=pdf',concat('-output-directory=',$tmp-path),concat($tmp-path,$tmp-file,'.tex')),' ')"/> 
     <p:input port="source"> 
      <p:empty/> 
     </p:input> 
     </p:exec> 
     <my:latex-exec> 
     <p:with-option name="latex-exec" select="$latex-exec"/> 
     <p:with-option name="latex-repeat" select="$latex-repeat - 1"/> 
     <p:with-option name="tmp-path" select="$tmp-path"/> 
     <p:with-option name="tmp-file" select="$tmp-file"/> 
     </my:latex-exec> 
    </p:otherwise> 
    </p:choose> 
</p:declare-step> 
+0

В моем примере не генерируются никакой ошибки, вероятно, потому, выберите выражение игнорируется все вместе, когда вход пуст? Если предоставляется допустимый, непустой вход, [err: XD0016] (http://www.w3.org/TR/xproc/#err.inline.D0016) (не err: XD0001). Итак, ap: for-each со следующим объявлением источника не выдает ошибок для любого выражения XPath и никогда не будет итерации ?: ' ' Тогда, почему бы разрешить ap: пусто как источник итерации? – FRNS

+0

Ваше альтернативное предложение должно сделать трюк. Я даю другое альтернативное решение, которое поддерживает функциональность итерации, отделенную от подзаголовка (см. Мой ответ). К сожалению, и ваше, и мое решение приходят немного долго, я бы полюбил более простой подход к итерациям. – FRNS

0

Как уже упоминалось Vojtěch Toman, цикл p: for-each не может перебирать атомные значения [XD0016]. Поскольку это ограничение не применяется к эквиваленту цикла XSLT 2.0, мы можем определить наш собственный шаг p: xslt для создания последовательности узлов XML в соответствии с количеством желаемых итераций. Затем эту последовательность можно использовать как вход для p: for-each.

Стадия итератора будет выглядеть следующим образом:

<p:declare-step version="1.0" 
    xmlns:p="http://www.w3.org/ns/xproc" 
    xmlns:c="http://www.w3.org/ns/xproc-step" 
    xmlns:my="http://example.org/iterate" 
    type="my:iterator"> 

    <p:option name="iterate" required="true"/> 

    <p:input port="source"/> 
    <p:output port="result" sequence="true"/> 

    <p:xslt name="iterator" template-name="iterator"> 
     <p:with-param name="iterator" select="$iterate"/> 
     <p:input port="stylesheet"> 
      <p:inline> 
       <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0"> 
        <xsl:param name="iterator"/> 
        <xsl:template name="iterator"> 
         <xsl:for-each select="(1 to xs:integer($iterator))"> 
          <xsl:result-document href="{position()}"> 
           <iterate/> 
          </xsl:result-document> 
         </xsl:for-each> 
        </xsl:template> 
       </xsl:stylesheet> 
      </p:inline> 
     </p:input> 
     <p:input port="source"> 
      <p:empty/> 
     </p:input> 
    </p:xslt> 

    <p:sink/> 

    <p:identity> 
     <p:input port="source"> 
      <p:pipe port="secondary" step="iterator"/> 
     </p:input> 
    </p:identity> 

</p:declare-step> 

пример использование нового шага итератор будет выглядеть следующим образом:

<p:declare-step version="1.0" 
    xmlns:p="http://www.w3.org/ns/xproc" 
    xmlns:c="http://www.w3.org/ns/xproc-step" 
    xmlns:my="http://example.org/iterate"> 

    <p:import href="iterate.xpl"/> 

    <!-- pre-processing -->  

    <my:iterator> 
     <p:with-option name="iterate" select="3"/> 
    </my:iterator> 
    <p:for-each> 

     <!-- sub-pipeline --> 

    </p:for-each> 

</p:declare-step>