10

xsl:for-eachで発生した反復を保存するにはどうすればよいですか?(XSLの変数は不変です)

私の目標は、特定のレベルの任意のノードの子の最大数を見つけることです。

たとえば、この調査の質問には2つ以下の応答ノードがあることを印刷したい場合があります。

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="testing.xsl"?>
<Survey>
  <Question>
    <Response text="Website" />
    <Response text="Print Ad" />
  </Question>
  <Question>
    <Response text="Yes" />
  </Question>
</Survey>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
  <html>
  <head>
  </head>
  <body>
    <xsl:for-each select="Survey">
      The survey has <xsl:value-of select="count(child::Question)"/> questions.  
      <br />
      <xsl:variable name="counter">0</xsl:variable>
      <xsl:for-each select="Question">
        <!-- TODO: increment the counter ??????? -->
      </xsl:for-each>
      No more than <xsl:value-of select="$counter"/> responses were returned for any question.
    </xsl:for-each>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>
4

1 に答える 1

10

XSLTは関数型言語であり、変数は不変であるため、「xsl:for-eachで発生した反復を保存」することはありません。

次の変換は、必要な最大値を見つけます。

<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 = "maximum">
        <xsl:with-param name = "pNodes" select = "* / Question" />
      </ xsl:call-template>
    </ xsl:template>

    <xsl:template name = "maximum">
      <xsl:param name = "pNodes" />

      <xsl:variable name = "vNumNodes" select = "count($ pNodes)" />

      <xsl:choose>
        <xsl:when test = "$ vNumNodes = 1">
          <xsl:value-of select = "count($ pNodes [1] / Response)" />
        </ xsl:when>
        <xsl:それ以外の場合>
          <xsl:variable name = "vHalf"
               select = "floor($ vNumNodes div 2)" />

          <xsl:variable name = "vMax1">
           <xsl:call-template name = "maximum">
            <xsl:with-param name = "pNodes"
                 select = "$ pNodes [not(position()> $ vHalf)]" />
           </ xsl:call-template>
          </ xsl:variable>

          <xsl:variable name = "vMax2">
           <xsl:call-template name = "maximum">
            <xsl:with-param name = "pNodes"
                 select = "$ pNodes [position()> $ vHalf]" />
           </ xsl:call-template>
          </ xsl:variable>

          <xsl:value-of select =
           "$ vMax1 *($ vMax1> = $ vMax2)+ $ vMax2 *($ vMax2> $ vMax1)" />
        </ xsl:それ以外の場合>
      </ xsl:choose>
    </ xsl:template>
</ xsl:stylesheet>

提供されたXMLドキュメントに適用する場合:

<調査>
    <質問>
        <Response text = "Website" />
        <Response text = "Print Ad" />
    </質問>
    <質問>
        <Response text = "Yes" />
    </質問>
</調査>

必要な結果が生成されます。

2

次の点に注意してください。「 」という名前のテンプレートmaximumは、それ自体を再帰的に呼び出し、再帰スタックの深さを最小化するためにDVC(分割統治法)を実装します。ノードのリストは2つに分割され、2つのリストの最大値が(再帰的に)計算され、2つのうち大きい方が返されます。

于 2008-12-04T00:56:04.993 に答える