0

XSLT を使用してヒープ ソート アルゴリズムを記述しようとしていますが、トークン化された値を格納するために使用される変数の値を交換するのに苦労しています。値を比較するためのメソッド heapify を作成し、大きい方の値を現在のインデックスにスワップします。親リストの値を交換するように指示してください。

<xsl:template match="/">

      <xsl:variable name="tokenizedSample" select="tokenize(.,' ')">             
    </xsl:variable>
    <!--<xsl:value-of select="."/>-->
    <xsl:call-template name="BuildHeap">
      <xsl:with-param name="intList" select="$tokenizedSample"/>
    </xsl:call-template>
  </xsl:template>



  <xsl:template name="BuildHeap">
   <xsl:param name="intList"/>
      <xsl:for-each select="$intList">
        <xsl:call-template name="Heapify">
          <xsl:with-param name="newintList" select="$intList"/>
          <xsl:with-param name="index"  select="position()"/>
        </xsl:call-template>
      </xsl:for-each>
 </xsl:template>



  <xsl:template name="Heapify">    
    <xsl:param name="newintList"/>
    <xsl:param name="index"/>
    <xsl:variable name="stringval">
      <xsl:text></xsl:text>
    </xsl:variable>
    <xsl:variable name="vIndex">
      <xsl:number value="$index" />
    </xsl:variable>

    <xsl:variable name="stringval" select="concat(($stringval),'is')"/>
    <xsl:if test="$newintList[$vIndex*2] &gt; $newintList[$vIndex*1]  and $newintList[$vIndex*2] &gt; $newintList[($vIndex*2)+1] ">

    <!—swap the values of ith position with 2ith position-->

      <xsl:for-each select="$newintList">
        <xsl:if test="position()=$vIndex">
          <xsl:value-of select="$newintList[$vIndex*2]"/>
          <xsl:value-of select="$stringval"/>
          <xsl:variable name="stringval" select="concat(($stringval),'is',$newintList[$vIndex*2])"/>
          <xsl:value-of select="$stringval"/>
        </xsl:if>

        <xsl:if test="position()=($vIndex*2)">
          <xsl:value-of select="$stringval"/>
          <xsl:variable name="stringval" select="concat(($stringval),'is')"/>
          <xsl:value-of select="$stringval"/>
          <xsl:variable name="stringval" select="concat(($stringval),'is',$newintList[$vIndex*1])"/>
        </xsl:if>

      </xsl:for-each>

<xsl:value-of select="$stringval"/>
    </xsl:if>


    <xsl:if test="$newintList[($vIndex*2)+1] &gt; $newintList[$vIndex*1]  and $newintList[($vIndex*2)+1] &gt; $newintList[$vIndex*2] ">
    <!—swap the values of ith position with 2i+1th position-->

    </xsl:if>

  </xsl:template>
4

2 に答える 2

1

I. XSLT 2.0 ソリューションは次のとおりです。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:sequence select="my:swap(/*/*, 3, 7)"/>
 </xsl:template>

 <xsl:function name="my:swap" as="item()*">
  <xsl:param name="pSeq" as="item()*"/>
  <xsl:param name="pPos1" as="xs:integer"/>
  <xsl:param name="pPos2" as="xs:integer"/>

  <xsl:sequence select=
   "$pSeq[position() lt $pPos1],
    $pSeq[$pPos2],
    $pSeq[position() gt $pPos1 and position() lt $pPos2],
    $pSeq[$pPos1],
    $pSeq[position() gt $pPos2]
   "/>
 </xsl:function>
</xsl:stylesheet>

この変換が次の XML ドキュメントに適用される場合:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

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

<num>01</num>
<num>02</num>
<num>07</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>03</num>
<num>08</num>
<num>09</num>
<num>10</num>

Ⅱ.同等の XSLT 1.0 ソリューション:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:call-template name="swap">
   <xsl:with-param name="pSeq" select="/*/*"/>
   <xsl:with-param name="pPos1" select="3"/>
   <xsl:with-param name="pPos2" select="7"/>
  </xsl:call-template>
 </xsl:template>

 <xsl:template name="swap">
  <xsl:param name="pSeq"/>
  <xsl:param name="pPos1"/>
  <xsl:param name="pPos2"/>

  <xsl:copy-of select="$pSeq[$pPos1 > position()]"/>
  <xsl:copy-of select="$pSeq[$pPos2]"/>
  <xsl:copy-of select="$pSeq[position() > $pPos1 and $pPos2 > position()]"/>
  <xsl:copy-of select="$pSeq[$pPos1]"/>
  <xsl:copy-of select="$pSeq[position() > $pPos2]"/>
 </xsl:template>
</xsl:stylesheet>

この変換を同じ XML ドキュメント (上記) に適用すると、同じ正しい結果が生成されます。

<num>01</num>
<num>02</num>
<num>07</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>03</num>
<num>08</num>
<num>09</num>
<num>10</num>
于 2012-11-19T01:18:15.057 に答える