【问题标题】:XML XSL issuesXML XSL 问题
【发布时间】:2009-05-27 17:24:23
【问题描述】:

我有一个包含大约 150 个条目的 xml 文档。我以几种方式对条目进行排序。一个是按字母顺序显示的,通过 XSLT 显示并且效果很好,其他的按类别和解决方案,存在逐行交替条带颜色的问题。

当我遍历未显示的条目时出现问题,即使它们未显示,它们似乎也包含在计数中。我之前在匿名用户下问过这个问题,希望这次我更清楚。

感谢您的帮助。

XML 文档。

<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>

【问题讨论】:

    标签: xml xslt xhtml


    【解决方案1】:

    第一:尽量避免&lt;xsl:for-each&gt;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>
    

    编辑:

    您可以使用&lt;xsl:key&gt; 来加快选择过程,但这只有在同一转换过程中重复查询同一数据时才会产生积极影响。

    <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 ... -->
    

    【讨论】:

      【解决方案2】:

      @Tomalak 总是 胜过我(提供更好、更详细的答案)!

      行交替的问题在于两行:

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

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

      发生的情况是您选择了与上述谓词条件匹配的节点集。处理器在循环的其余部分记住这一点。然后应用另一个条件,进一步限制处理的节点(但不循环)。

      您使用 position() 函数测试循环内的位置...它包含总数。 &lt;xsl:for... 循环匹配的节点数(不排除被 &lt;xsl:if 条件过滤掉的节点。

      一种解决方案是结合xsl:for-eachxsl:if 条件:

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

      当然,这个解释只是为了说明这一点。 Tomalak 关于避免使用 for-each 的观点非常有效,他的解决方案也很棒。

      【讨论】:

      • +1 用于解释为什么问题中的解决方案不起作用:)
      • 顺便说一句:您的个人资料显示您在印度,从这里到地球的另一端。理论上,你应该快半天。 ;-)
      • @Tomalak:我比较慢,因为问题需要更长的时间才能到达这里......服务器在美国:P:P
      猜你喜欢
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 2021-01-03
      • 2011-06-13
      • 1970-01-01
      • 2017-02-18
      • 2011-03-15
      • 1970-01-01
      相关资源
      最近更新 更多