XSLT apply-templates рекурсивность Doom! - PullRequest
2 голосов
/ 13 мая 2011

Мне нужна следующая структура документа XML:

<option_set id="1">
  <option>Yes</option>
  <option>No</option>
  <option>Maybe</option>
</option_set>

<question option_set="1">
  <text>Do you like cake?</text>
</question>
<question option_set="1">
  <text>Is the cake a lie?</text>
</question>

В интересах сохранения СУХОГО, идея состоит в том, чтобы иметь ряд различных вопросов, которые имеют общие наборы опций.Затем они могут быть построены с использованием XSLT.Мои шаблоны выглядят следующим образом:

<xsl:template match="question[@option_set and not(option)]">
  <!-- Build a whole question with its options
       (copy the options across and then apply-templates?) -->
</xsl:template>

<xsl:template match="question[option]">
  <!-- Match a whole question, with options, for making pretty HTML out of -->
</xsl:template>

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

<question>
  <text>Do you like cake?</text>
  <option>Yes</option>
  <option>No</option>
  <option>Maybe</option>
</question>

... Который затем может быть сопоставлен с нижним шаблоном и вставлен в мой HTML-документ.Мой вопрос заключается в том, как мне создать (верхний) шаблон, который на самом деле это делает.Я близок, но это все еще не работает:

<xsl:template match="question[@option_set and not(option)]">
  <xsl:variable name="optset" select="@option_set"/>

  <xsl:copy>
    <xsl:copy-of select="text"/>
    <xsl:copy-of select="//option_set[@id=$optset]/option"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

Преобразованный блок вопросов вместе с его параметрами копируется в документ вместо того, чтобы быть выбранным верхним шаблоном и сделанв красивый HTML.

Если я попытаюсь <xsl:apply-templates select="."/>, я попаду в бесконечный цикл.

Ответы [ 2 ]

2 голосов
/ 13 мая 2011

Не уверен, что вы в конечном итоге пытаетесь сделать, но это может помочь вам.

<xsl:template match="question">
  <xsl:value-of select="text"/>: 
  <select>
     <xsl:variable name="option_set_id" select="@option_set"/>
     <xsl:apply-templates select="option | //option_set[@id=$option_set_id]/option"/>
  </select>
</xsl:template>

<xsl:template match="option">
   <option>
      <xsl:value-of select="."/>
   </option>
</xsl:template>

Существуют твики, такие как добавление ключа выше, проверка на неиспользуемые option_sets и т. Д., Но этоначать.

2 голосов
/ 13 мая 2011
<xsl:key name="kOptionSet" match="option_set" use="@id" />

<xsl:template match="question">
  <xsl:copy>
    <xsl:copy-of select="text" />
    <xsl:copy-of select="key('kOptionSet', @option_set)/option" />
    <xsl:apply-templates />
  </xsl:copy>
</xsl:template>

Должен делать то, что ты хочешь.Я не уверен, почему ты рекурсивен в первую очередь.

...