2009-05-27 58 views
0

我有一個xml文檔,大約有150個條目。我正在用幾種方式排序條目。一個是按字母順序排列的,它通過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 2009-05-27 18:05:53

+0

謝謝,謝謝,謝謝! – BillZ 2009-05-27 18:55:12

1

@Tomalak 總是打我給它(一個更好的和更詳細的解答)!

中的行交替的問題在於兩行:

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

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

會發生什麼事是你選擇一個節點集匹配上面的謂詞條件。處理器在循環的其餘部分記住這一點。然後應用另一個條件,進一步限制處理的節點(但不會循環)。

您可以使用position()函數...來測試循環中的位置,該函數保存總數爲0。

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

當然,這樣的解釋:節點由<xsl:for...環(不排除由<xsl:if條件濾出節點

的溶液是將xsl:for-eachxsl:if條件結合匹配只是爲了說明這一點。 Tomalak關於避免使用for-each的觀點非常有效,他的解決方案非常棒。