2012-01-02 8 views
1

私はxmlからいくつかの整数を得て、1と取得した数の間のすべての数を取得したいと思います。forループin xsltページ

これらの数値を列名として挿入したいとします。

できますか?

ありがとうございました。

答えて

5

I. XSLT 2.0溶液

<xsl:sequence select="1 to $N"/> 

II。 XSLT 1.0 DVCソリューション

@nd(プリミティブ再帰を使用して)の回答が良いです。

しかし、十分に大きな長さ(1000以上)で一連の数値を生成する場合、プリミティブ再帰は、過度の再帰により、通常スタックオーバーフローで異常終了します。

DVC(分割統治)メソッドは、任意の実用的な場合のコールスタックオーバーフローを回避するために使用することができる。この変換は、任意のXML文書(使用せず)に印加さ​​れる

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 

    <xsl:template match="/"> 
     <xsl:call-template name="displayNumbers"> 
     <xsl:with-param name="pStart" select="1"/> 
     <xsl:with-param name="pEnd" select="1000000"/> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="displayNumbers"> 
     <xsl:param name="pStart"/> 
     <xsl:param name="pEnd"/> 

     <xsl:if test="not($pStart > $pEnd)"> 
     <xsl:choose> 
     <xsl:when test="$pStart = $pEnd"> 
      <xsl:value-of select="$pStart"/> 
      <xsl:text>&#xA;</xsl:text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:variable name="vMid" select= 
      "floor(($pStart + $pEnd) div 2)"/> 
      <xsl:call-template name="displayNumbers"> 
      <xsl:with-param name="pStart" select="$pStart"/> 
      <xsl:with-param name="pEnd" select="$vMid"/> 
      </xsl:call-template> 
      <xsl:call-template name="displayNumbers"> 
      <xsl:with-param name="pStart" select="$vMid+1"/> 
      <xsl:with-param name="pEnd" select="$pEnd"/> 
      </xsl:call-template> 
     </xsl:otherwise> 
     </xsl:choose> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

、それを数字を1から100万まで出力します。この変換中のコールスタックの最大部は19(log2(N))です。


3である。非再帰的XSLT 1。0溶液

生成される数列の長さ(より正確には、そのようなXSLTスタイルシート自体としてXML文書内の利用可能なノード(の数を超えない大きすぎない場合には))、我々はPiez methodとして知られる非再帰溶液、使用することができます。この変換は、(使用されていない任意のXML文書に適用される場合)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:variable name="vDoc" select="document('')"/> 
<xsl:variable name="vNodes" select= 
"$vDoc//node() | $vDoc//@* | $vDoc//namespace::*"/> 

<xsl:template match="/"> 
    <xsl:for-each select="$vNodes[not(position() > 40)]"> 
     <xsl:value-of select="position()"/> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

をそれが1から40に番号を生成します:

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
1

最初にアドバイスしてください:通常、このような質問は、物事が別のやり方で、よりXSLT風の方法で行われるべきであることを示します。ソースXMLツリーに一致するテンプレートでposition()を使用して現在のノードのインデックスを取得します。

しかし、必要ならば、1と任意の数の間のすべての整数を取得できます。しかし、あなたがXSLTで変数を再割り当てすることはできませんように、それを行うための標準的な方法は、再帰を使用することです:

<xsl:template name="counter"> 
    <xsl:param name="current"/> 
    <xsl:param name="max"/> 
    <xsl:if test=" $max >= $current"> 
    <!-- do whatever you want to do with the current item here --> 
    <th><xsl:value-of select="$current"/></th> 

    <!-- increase the counter for the recursive call --> 
    <xsl:call-template name="counter"> 
     <xsl:with-param name="current" select="$current + 1"/> 
     <xsl:with-param name="max" select="$max"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

次に、開始値と自分の最大数で再帰テンプレートを呼び出します。

<xsl:call-template name="counter"> 
    <xsl:with-param name="current" select="1"/> 
    <xsl:with-param name="max" select="$gotten-number"/> 
</xsl:call-template>