使用XSLT 1.0我需要转换它:
<form>
<question NumOfColumns="3">
<title>Colors</title>
<answer>red</answer>
<answer>orange</answer>
<answer>yellow</answer>
<answer>green</answer>
<answer>blue</answer>
<answer>indigo</answer>
<answer>violet</answer>
</question>
</form>
进入这个:
<h2 class="question">Colors</h2>
<div class="answersrow">
<input type="checkbox" name="colors" value="red" id="red" /> <label for="red">red</label>
<input type="checkbox" name="colors" value="orange" id="orange" /> <label for="orange">orange</label>
<input type="checkbox" name="colors" value="yellow" id="yellow" /> <label for="yellow">yellow</label>
</div>
<div class="answersrow">
<input type="checkbox" name="colors" value="green" id="green" /> <label for="green">green</label>
<input type="checkbox" name="colors" value="blue" id="blue" /> <label for="blue">blue</label>
<input type="checkbox" name="colors" value="indigo" id="indigo" /> <label for="indigo">indigo</label>
</div>
<div class="answersrow">
<input type="checkbox" name="colors" value="green" id="green" /> <label for="green">green</label>
</div>
问题节点中的NumOfColumns指示输出答案div时要使用的列数。对于每个节点,我可以使用以下方式获取其行:
ceiling(position()div parent :: * / @ NumOfColumns)
这很好用;我可以输出正确的整数。但我不能让密钥/分组工作,我不确定问题出在哪里。
我认为关键是:
<xsl:key name="answersrow" match="form/question/answer[ceiling( position() div parent::*/@NumOfColumns) = parent::*/@NumOfColumns]" use="." />
然后我可以使用:
检索节点<xsl:for-each select="key('answersrow', answer)">
没有运气。有人有解决方案吗?或者这在XSLT 1.0中是不可行的?
答案 0 :(得分:0)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="question">
<h2 class="{local-name()}">
<xsl:apply-templates select="title"/>
</h2>
<!--Select the answers that will begin the groups.
Apply templates in mode group and pass in the number of columns -->
<xsl:variable name="cols" select="@NumOfColumns"/>
<xsl:apply-templates select="answer[position() mod $cols = 1]"
mode="group" >
<xsl:with-param name="cols" select="$cols"/>
</xsl:apply-templates>
</xsl:template>
<!--Group the answers as children of the div -->
<xsl:template match="answer" mode="group">
<xsl:param name="cols"/>
<div class="answersrow">
<xsl:apply-templates
select=".|following-sibling::answer[position() < $cols]"/>
</div>
</xsl:template>
<!--normal rendering for each answer -->
<xsl:template match="answer">
<input type="checkbox" name="colors" value="{.}" id="{.}" />
<label for="{.}">
<xsl:value-of select="."/>
</label>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
<强>予。 XSLT 1.0:比其他答案更简单(没有参数)和稍微更短的解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vNumCols" select="/*/*/@NumOfColumns"/>
<xsl:template match="/*">
<h2 class="question"><xsl:value-of select="*/title"/></h2>
<xsl:apply-templates select=
"*/answer[position() mod $vNumCols = 1]"/>
</xsl:template>
<xsl:template match="answer">
<div class="answersrow">
<xsl:apply-templates mode="inGroup" select=
". | following-sibling::*[not(position() >= $vNumCols)]"/>
</div>
</xsl:template>
<xsl:template match="answer" mode="inGroup">
<input type="checkbox" name="colors"
value="{.}" id="{.}" />
<label for="{.}"><xsl:value-of select="."/></label>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<form>
<question NumOfColumns="3">
<title>Colors</title>
<answer>red</answer>
<answer>orange</answer>
<answer>yellow</answer>
<answer>green</answer>
<answer>blue</answer>
<answer>indigo</answer>
<answer>violet</answer>
</question>
</form>
产生了想要的正确结果:
<h2 class="question">Colors</h2>
<div class="answersrow">
<input type="checkbox" name="colors" value="red" id="red"/>
<label for="red">red</label>
<input type="checkbox" name="colors" value="orange" id="orange"/>
<label for="orange">orange</label>
<input type="checkbox" name="colors" value="yellow" id="yellow"/>
<label for="yellow">yellow</label>
</div>
<div class="answersrow">
<input type="checkbox" name="colors" value="green" id="green"/>
<label for="green">green</label>
<input type="checkbox" name="colors" value="blue" id="blue"/>
<label for="blue">blue</label>
<input type="checkbox" name="colors" value="indigo" id="indigo"/>
<label for="indigo">indigo</label>
</div>
<div class="answersrow">
<input type="checkbox" name="colors" value="violet" id="violet"/>
<label for="violet">violet</label>
</div>
<强> II。 XSLT 2.0解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vNumCols" select="/*/*/@NumOfColumns" as="xs:integer"/>
<xsl:template match="/*">
<h2 class="question"><xsl:value-of select="*/title"/></h2>
<xsl:for-each-group select="*/answer"
group-adjacent="(position() -1) idiv $vNumCols">
<div class="answersrow">
<xsl:apply-templates select="current-group()"/>
</div>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="answer">
<input type="checkbox" name="colors"
value="{.}" id="{.}" />
<label for="{.}"><xsl:value-of select="."/></label>
</xsl:template>
</xsl:stylesheet>