Проблемы XML XSL - PullRequest
       11

Проблемы XML XSL

0 голосов
/ 27 мая 2009

У меня есть документ XML с около 150 записей. Я сортирую записи по нескольким модам. Один из них - алфавитный, который отображается через XSLT и работает отлично, другие - по категориям и решениям, в которых есть проблемы с чередованием цвета полос по строке.

Проблема возникает, когда я перебираю записи, которые не отображаются, кажется, что они включены в подсчет, даже если они не отображаются. Я задал этот вопрос однажды под анонимным пользователем, надеюсь, в этот раз я проясню.

Спасибо за помощь.

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 Call

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

2 голосов
/ 27 мая 2009

Во-первых: старайтесь избегать <xsl:for-each>. В большинстве случаев это плохой выбор.

Второй: выберите только те узлы, которые вы хотите вывести, и чередование строк будет работать:

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

Edit:

Вы можете использовать <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 ... -->
1 голос
/ 27 мая 2009

@ Томалак всегда побеждает меня (с лучшим и более подробным ответом)!

Проблема чередования строк заключается в двух строках:

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

и

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

В результате вы выбираете набор узлов, соответствующий вышеуказанному условию предиката. Процессор запоминает это до конца цикла. Затем вы применяете другое условие, которое дополнительно ограничивает обрабатываемые узлы (но не зацикливается).

Вы проверяете положение в цикле, используя функцию position(), которая содержит общее число. узлов, соответствующих циклу <xsl:for... (, не исключая узлы, отфильтрованные по условию <xsl:if. )

Решением было бы объединить условия xsl:for-each и xsl:if:

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

Конечно, это объяснение только для иллюстрации сути. Идея Томалака о том, чтобы избегать использования for-each, очень верна, и его решение просто потрясающе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...