我必须遵循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>
为了保持DRY的利益,我们的想法是拥有许多不同的问题,这些问题有着共同的选择。然后可以使用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="."/>
,那么我会陷入无限循环。
答案 0 :(得分:2)
<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>
应该做你想做的事。我不确定你为什么要首先递归。
答案 1 :(得分:2)
不确定你最终要做什么,但这可能对你有帮助。
<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等,但这会让你开始。