3

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 を出力するときに使用する列の数を示します。ノードごとに、次を使用してその行を取得できます。

天井 (position() div 親::*/@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 では実行できませんか?

4

2 に答える 2

0

I. 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>
于 2012-03-11T01:56:51.987 に答える
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() &lt; $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>
于 2012-03-11T00:51:17.350 に答える