我今天开始使用xsl进行第一次冒险,希望能够做到这一点"轻松"脚本很快。 现在4小时后,我仍然不知道它为什么会产生2次......
我需要你的帮助才能在我的脚本中找到错误,因为我自己无法找到它......
我正在使用XSL创建基于XML的HTML表单
我基本上有一个自动创建两次的模板。我只想要<div class="columnDiv">
中的那个。
屏幕截图 error reasult 屏幕截图显示我想要的内容 achieve。
我的XML
<?xml version="1.0" encoding="UTF-8"?>
<labels>
<options>
<option type="Top Text 1"/>
<option type="Top Text 2"/>
<option type="Top Text 2"/>
</options>
<statuses>
<status type="Correct">
<answer description="Yes"/>
<answer description="No"/>
</status>
<status type="Error - Type 1">
<answer description="Option 1"/>
<answer description="Option 2"/>
<answer description="Option 3"/>
<answer description="Option 4"/>
</status>
<status type="Error - Type 2">
<answer description="Option 1"/>
<answer description="Option 2"/>
<answer description="Option 3"/>
<answer description="Option 4"/>
</status>
</statuses>
</labels>
我的XSL
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<form method="POST" action="new-process.php">
<div class="mainC">
<xsl:apply-templates/>
</div>
<input type="submit" name="submit" value="Submit" />
</form>
</xsl:template>
<xsl:template match="options">
<xsl:for-each select="option">
<div class="columnDiv">
<h3><xsl:value-of select="@type"/></h3>
<xsl:apply-templates select="/labels/statuses"/>
</div>
</xsl:for-each>
</xsl:template>
<xsl:template match="status">
<xsl:for-each select=".">
<label><xsl:value-of select ="@type"/></label>
<select>
<xsl:for-each select="answer">
<option><xsl:value-of select="@description"/></option>
</xsl:for-each>
</select>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
关于所需输出的评论的当前输出
<?xml version="1.0" encoding="UTF-8"?>
<form method="POST" action="new-process.php">
<div class="mainC">
<div class="columnDiv">
<h3>Top Text 1</h3>
<label>Correct</label><select><option>Yes</option><option>No</option></select>
<label>Error - Type 1</label><select><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option></select>
<label>Error - Type 2</label><select><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option></select>
</div>
<div class="columnDiv">
<h3>Top Text 2</h3>
<label>Correct</label><select><option>Yes</option><option>No</option></select>
<label>Error - Type 1</label><select><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option></select>
<label>Error - Type 2</label><select><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option></select>
</div>
<div class="columnDiv">
<h3>Top Text 2</h3>
<label>Correct</label><select><option>Yes</option><option>No</option></select>
<label>Error - Type 1</label><select><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option></select>
<label>Error - Type 2</label><select><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option></select>
</div>
<!-- \ this is the output that I do no want \ -->
<label>Correct</label><select><option>Yes</option><option>No</option></select>
<label>Error - Type 1</label><select><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option></select>
<label>Error - Type 2</label><select><option>Option 1</option><option>Option 2</option><option>Option 3</option><option>Option 4</option></select>
<!-- / this is the output that I do no want / -->
</div>
<input type="submit" name="submit" value="Submit"/>
</form>
答案 0 :(得分:3)
根据评论,只需在您的第一个apply-templates语句中添加select="/labels/options"
后即可获得解决方案。 @TimC在his answer中给出了很好的解释。
也就是说,您在代码中也使用了很多for-each
个循环。通常使用XSL,在这种情况下使用模板会更好,因为它可以使代码更清晰*。这是一个经过调整的版本,删除了这些循环:http://xsltfiddle.liberty-development.net/bFDb2BX/3
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<form method="POST" action="new-process.php">
<div class="mainC">
<xsl:apply-templates select="/labels/options"/>
</div>
<input type="submit" name="submit" value="Submit" />
</form>
</xsl:template>
<xsl:template match="options/option">
<div class="columnDiv">
<h3><xsl:value-of select="@type"/></h3>
<xsl:apply-templates select="/labels/statuses"/>
</div>
</xsl:template>
<xsl:template match="status">
<label><xsl:value-of select ="@type"/></label>
<select>
<xsl:apply-templates select="./answer"/>
</select>
</xsl:template>
<xsl:template match="answer">
<option><xsl:value-of select="@description"/></option>
</xsl:template>
</xsl:stylesheet>
*我最初表示这也改善了并行处理;但正如Martin在评论中指出的那样,一些引擎也支持for-each
的并行处理;而且我找不到任何文件来支持我原来的陈述;所以怀疑它是伪造的。
答案 1 :(得分:1)
你根本没有开始,但你现在需要了解XSLT的Built in Template Rules。这些是在XSLT中没有匹配模板时使用的模板。
您有一个与文档节点/
匹配的模板,您可以在其中执行<xsl:apply-templates />
。这将选择您没有模板的label
节点。所以默认模板就是这个......
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
这将选择options
和statuses
个节点。您有一个匹配options
的模板,所以这很好,但不是匹配的statuses
,所以内置的模板再次启动。
但是在您的options
模板中,<xsl:apply-templates select="/labels/statuses"/>
最终会导致statuses
(以及子status
个节点)被选中两次。
一种解决方案是将<xsl:apply-templates />
节点中的/
更改为仅明确选择options
,就像这样......
<xsl:template match="/">
<form method="POST" action="new-process.php">
<div class="mainC">
<xsl:apply-templates select="labels/options"/>
</div>
<input type="submit" name="submit" value="Submit" />
</form>
</xsl:template>