2009-05-27 13 views
0

私は約150のエントリを持つXML文書を持っています。私はいくつかの方法でエントリをソートしています。 1つはアルファベット順で、XSLTを介して表示され、完全に動作します。他はカテゴリと解決策であり、行ごとにバンディングを交互に行う問題があります。XML XSLの問題

問題は、表示されていない項目を反復処理するときに発生します。表示されていないにもかかわらずカウントに含まれているようです。私はこの質問を匿名ユーザーの前に一度尋ねましたが、今回はもっと賢明です。

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

XML Doc。

<case-studies> 
    <!-- #### X #### --> 
    <case-study>  
     <name>Entry 1</name> 
     <category solution="Performance">Medical</category> 
     <category solution="Medical">Security</category> 
     <category solution="Industry">Medical</category> 
     <category solution="A-Z">X</category> 
    </case-study> 

<!-- #### Y #### --> 
    <case-study>  
     <name>Entry 2</name> 
     <category solution="Industry">Education</category> 
     <category solution="Convergence">Education</category> 
     <category solution="A-Z">Y</category> 
    </case-study> 

</case-studies> 

XSLTコール

<% 
     Dim mm_xsl As MM.XSLTransform = new MM.XSLTransform() 
     mm_xsl.setXML(Server.MapPath("/data/xml/case-studies/case-studiesTest.xml")) 
     mm_xsl.setXSL(Server.MapPath("/data/xslt/case-studies/categoryLandingOther.xsl")) 
     mm_xsl.addParameter("solName", "Industry") 
     mm_xsl.addParameter("catName", "Business services") 
     Response.write(mm_xsl.Transform()) 
    %> 

XSLTの一部

<xsl:for-each select="case-studies/case-study/category[. = $catName]">  

    <!--xsl:sort select="../name" /--> 
    <xsl:if test="@solution[. = $solName]"> 


     <tr> 
     <xsl:if test="(position() mod 2 = 1)"> 
      <xsl:attribute name="bgcolor">#e7e7e7</xsl:attribute>     
     </xsl:if>  
      <td class="cell1">     
      </td> 
      <td class="cell2" style="padding-top:2px;">» <a href="{../url}"><xsl:value-of select="../name"/></a></td> 
      <td class="cell3"> 
      <xsl:for-each select="../solutionType">   
       <div class="clearRight"><xsl:value-of select="."/></div> 
      </xsl:for-each>     
      </td> 
     </tr> 

    </xsl:if> 
</xsl:for-each> 

答えて

2

まず:<xsl:for-each>を避けるようにしてください。 It's a bad choice most of the time.

第二:出力にしたいノードのみを選択して、行の交代は動作します:

<xsl:template match="/case-studies"> 
    <xsl:apply-templates select="case-study[ 
    category = $catName 
    and 
    category/@solution = $solName 
    ]"> 
    <xsl:sort select="name" /> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="case-study"> 
    <tr> 
    <xsl:if test="position() mod 2 = 1"> 
     <xsl:attribute name="bgcolor">#e7e7e7</xsl:attribute> 
    </xsl:if>  
    <td class="cell1" />     
    <td class="cell2" style="padding-top:2px;"> 
     <xsl:text>» </xsl:text> 
     <a href="{url}"><xsl:value-of select="name"/></a> 
    </td> 
    <td class="cell3"> 
     <xsl:apply-templates select="solutionType" /> 
    </td> 
    </tr> 
</xsl:template> 

<xsl:template match="solutionType"> 
    <div class="clearRight"> 
    <xsl:value-of select="."/> 
    </div> 
</xsl:template> 

編集:

あなたが選択プロセスをスピードアップするために<xsl:key>を使用していますが、このことができます同じ変換プロセス中に同じデータを繰り返しクエリすると、肯定的な効果しか得られません。

<xsl:key name="kCaseStudy" 
     match="case-study" 
     use="concat(category, category/@solution)" 
/> 

<!-- no need to be in "/case-studies" context this time --> 
<xsl:template match="/"> 
    <xsl:apply-templates select="key('kCaseStudy', concat($catName, $solName))"> 
    <xsl:sort select="name" /> 
    </xsl:apply-templates> 
</xsl:template> 

<!-- ... code that uses "key('kCaseStudy', ...)" again ... --> 
+0

恐ろしく........! – Cerebrus

+0

ありがとう、ありがとう、ありがとう! – BillZ

1

@Tomalak は常に(より良く、より詳細な回答で)、それに私を打ちます!何が起こることは、あなたが上記の述語条件に合致するノードセットを選択することである

<xsl:for-each select="case-studies/case-study/category[. = $catName]"> 

<xsl:if test="@solution[. = $solName]"> 

行の交互に問題が二行にあります。プロセッサはこれを残りのループに対して覚えています。次に、処理されたノードをさらに制限する別の条件を適用します(ただしループしません)。

ループ内の位置は、position() ...という関数を使用してテストします。 <xsl:for...ループによって一致ノード(<xsl:if条件によってフィルタリングノードを除外しない。)

溶液をxsl:for-eachxsl:if条件結合するであろう:この説明、もちろん

<xsl:for-each select="case-study/category[. = $catName and @solution = $solName]"> 

をその点を説明するだけです。 for-eachの使用を避けることについてのTomalakの主張は非常に有効であり、彼の解決策は素晴らしいです。

+0

質問の解決策がうまくいかない理由を説明するための+1 :) – Tomalak

+0

ところであなたのプロフィールはあなたがインドにいると言います、それはここから地球の半分です。理論的には、あなたは一日のうちの半分速くすべきです。 ;-) – Tomalak

+0

@Tomalak:質問がここに来るまでに時間がかかるので、遅いです...サーバーは米国にあります:P:P – Cerebrus