orbeon: применение преобразования xslt в xbl для связанного документа - PullRequest
1 голос
/ 02 августа 2011

В Orbeon Forms мне нужно создать компонент (используя XBL), который при привязке к экземпляру, как

<OCinstructionitem>
  <OCp>paragraph 1</OCp>
  <OCp>paragraph 2 <OCem>with italics part</OCem> rest of paragraph 2 </OCp>
</OCinstructionitem>

создает редактируемый div следующим образом:

<div contentEditable="true">
  <p>paragraph 1</p>
  <p>paragraph 2 <i>with italics part</i> rest of paragraph 2 </p>
</div>

Я думал, что мне нужно сделать это с помощью XSLT. Я работаю, когда преобразуемый XML-файл находится внутри документа xforms:

<oc:instructionitem>
   <OCinstructionitem>
      <!-- here the xml of above -->
      ...
   </OCinstructionitem>
</oc:instructionitem> 

но я хочу, чтобы XSLT работал на связанном узле, как в:

<oc:instructionitem ref="OCinstructionitem"/>

Однако я не могу получить доступ к связанному узлу из XSLT.

Мой вопрос: это просто невозможно? Или я должен изменить свой XBL?

Мой код XBL:

<xbl:binding id="oc-instructionitem" element="oc|instructionitem">
    <xbl:template xxbl:transform="oxf:xslt">
        <xsl:transform version="2.0">
              <xsl:template match="@*|node()" priority="-100">
                   <xsl:apply-templates select="@*|node()"/>
              </xsl:template>
              <xsl:template match="text()" priority="-100" mode="in-paragraph">
                  <xsl:copy>
                     <xsl:value-of select="."/>
                  </xsl:copy>
              </xsl:template>
              <xsl:template match="OCem" mode="in-paragraph">
                  <x:i><xsl:value-of select="."/></x:i>
              </xsl:template>
              <xsl:template match="OCp">
                  <x:div>
                      <xsl:apply-templates mode="in-paragraph"/>
                  </x:div>
              </xsl:template>
              <xsl:template match="/*">
                <x:div contentEditable="true">
                    <xsl:apply-templates/>
                </x:div>
            </xsl:template>
    </xsl:transform>
    </xbl:template>
</xbl:binding>

</xbl:xbl>

Любая помощь будет принята с благодарностью,

edit: после полезного комментария tohuwawohu (ниже) Кажется, вам нужно определить переменную, которая связана с данными экземпляра. Как это:

<xsl:template match="oc:instructionitem">
   <xforms:group xbl:attr="model context ref bind" xxbl:scope="outer">
      <xxforms:variable name="binding" as="node()?" xxbl:scope="inner" >
         <xxforms:sequence select="." xxbl:scope="outer"/>
      </xxforms:variable>
      <xforms:group xxbl:scope="inner">
         <!-- Variable pointing to external single-node binding -->
         <xforms:group ref="$binding">
              <xsl:call-template name="main"/>
         </xforms:group>
      </xforms:group>
   </xforms:group>
</xsl:template>
<xsl:template name="main">
    <x:div contentEditable="true">
       <xforms:repeat nodeset="*">
           <xsl:call-template name="paragraph"/>
       </xforms:repeat>
    </x:div>
</xsl:template>

Однако элементы XSLT по-прежнему не могут воздействовать на данные. Он может генерировать только элементы XFORMS, которые могут воздействовать на данные. Это означает, что что-то вроде никогда не будет выбрано. Вот почему в приведенном выше коде используются именованные шаблоны. Таким образом, вопрос остается открытым: можно ли сделать связанные данные доступными для кода xslt?

Мартейн

1 Ответ

0 голосов
/ 02 августа 2011

Я не проверял это, но я думаю, что это должно быть возможно путем нарушения инкапсуляции. Без этого ваш XBL будет иметь доступ только к содержимому связанного узла, как в третьем фрагменте кода. Если вы хотите, чтобы XBL обращался к данным экземпляра XForms, вам нужно будет объявить переменную внутри XBL, которая указывает на привязку одного узла связанного узла .

Вот фрагмент кода из примера Wiki:

<xforms:group xbl:attr="model context ref bind" xxbl:scope="outer">
    <xforms:group xxbl:scope="inner">
        <!-- Variable pointing to external single-node binding -->
        <xxforms:variable name="binding" as="node()?">
            <xxforms:sequence select="." xxbl:scope="outer"/>
        </xxforms:variable>
        ...
    </xforms:group>
</xforms:group>

Определив привязку к одному узлу следующим образом, должна быть возможность ссылаться на эту переменную и использовать ее для преобразования xslt. Просто замените элемент шаблона XSLT, соответствующий корневому узлу, и укажите его содержимое переменной $binding:

<xsl:transform version="2.0">
    <xsl:template match="@*|node()" priority="-100">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:template>
    <xsl:template match="text()" priority="-100" mode="in-paragraph">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="OCem" mode="in-paragraph">
        <x:i><xsl:value-of select="."/></x:i>
    </xsl:template>
    <xsl:template match="OCp">
        <x:div>
            <xsl:apply-templates mode="in-paragraph"/>
        </x:div>
    </xsl:template>
    <xsl:template match="oc:instructionitem">
        <xforms:group ref="$binding">
          <x:div contentEditable="true">
              <xsl:apply-templates/>
          </x:div>
        </xforms:group>
    </xsl:template>

Надеюсь, это работает для вас. Может быть, для этого требуется создать условия, если связанный узел (в вашем примере: oc:instructionitem) не пустой, поэтому xslt может обрабатывать как это содержимое, так и содержимое переменной $binding.

...