0

我是 XSLT 的新手,但最近我不得不编写自己的 xslt 来处理 XML,我写了一些东西,但我想问一下专业人士,如果我做得好,或者还有什么我可以做的提升。

我知道 XSLT 使用模板和东西,但在我的 XSLT 中,我认为测试中有太多可重复的东西......可以减少吗?

这是我的 XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">
  <xsl:output method="xml" indent="yes"/>
  <xsl:param name="Today" />
  <xsl:param name="ViewType" />
  <xsl:template match="/">
    <table>
        <tr>
            <th>Priority</th>
            <th>Title</th>
            <th>Due date</th>
        </tr>
      <xsl:apply-templates select="All_Results/Result">
        <xsl:sort select="duedate" />
      </xsl:apply-templates>
     </table>
  </xsl:template>

  <xsl:template match="Result">
    <xsl:variable name="varOverdue" select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string(duedate))) &lt; ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($Today)))" ddwrt:cf_explicit="1"/>
    <xsl:variable name="varOverduePlus14" select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string(duedate))) &lt; ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($Today)))+12096000000000" ddwrt:cf_explicit="1"/>
    <xsl:variable name="varOverdueToday" select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string(duedate))) = ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($Today)))" ddwrt:cf_explicit="1"/>
    <xsl:choose>
        <xsl:when test="$ViewType='active'">

            <xsl:if test="($varOverdue=0) and (taskstatus ='In Progress')">          
                <tr>                
                    <td><xsl:value-of select="priority"/></td>
                    <td>
                        <a>
                        <xsl:attribute name="href">
                          <xsl:value-of  select="url"/>
                        </xsl:attribute>
                        <xsl:attribute name="title">
                          <xsl:value-of select="title"/>
                        </xsl:attribute>
                        </a>                          
                    </td>
                    <td>
                        <xsl:value-of select="duedate"/>
                    </td>
                </tr>
            </xsl:if>

        </xsl:when>
        <xsl:when test="$ViewType='overdue'">
            <xsl:if test="($varOverdue=1) and (taskstatus !='Completed')">          
                <tr>                
                    <td><xsl:value-of select="priority"/></td>
                    <td>
                        <a>
                        <xsl:attribute name="href">
                          <xsl:value-of  select="url"/>
                        </xsl:attribute>
                        <xsl:attribute name="title">
                          <xsl:value-of select="title"/>
                        </xsl:attribute>
                        </a>                          
                    </td>
                    <td>
                        <xsl:attribute name="style">
                           color:red;
                        </xsl:attribute>
                        <xsl:value-of select="duedate"/>
                    </td>
                </tr>
            </xsl:if>
        </xsl:when>
        <xsl:when test="$ViewType='upcoming'">      
            <xsl:if test="(taskstatus !='Completed') and ($varOverduePlus14=1)">          
                <tr>                
                    <td><xsl:value-of select="priority"/></td>
                    <td>
                        <a>
                        <xsl:attribute name="href">
                          <xsl:value-of  select="url"/>
                        </xsl:attribute>
                        <xsl:attribute name="title">
                          <xsl:value-of select="title"/>
                        </xsl:attribute>
                        </a>                          
                    </td>
                    <td>
                        <xsl:if test="$varOverdue=1">
                            <xsl:attribute name="style">
                               color:red;
                            </xsl:attribute>
                        </xsl:if>
                        <xsl:value-of select="duedate"/>
                    </td>
                </tr>
            </xsl:if>           
        </xsl:when>
    </xsl:choose>

  </xsl:template>

</xsl:stylesheet>

XML 如下所示:

<All_Results>
    <Result>
      <id>1</id>
      <workid>2258</workid>
      ...
    </Result>
    <Result>
      <id>2</id>
      <workid>4537</workid>
      ....
    </Result>
    ...
</All_Results>

那么有没有办法改进我的 XSLT 来解析当前的 XML?

4

1 回答 1

1

是的,您应该能够大大巩固这一点,如下所示:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">
  <xsl:output method="xml" indent="yes"/>
  <xsl:param name="Today" />
  <xsl:param name="ViewType" />
  <xsl:template match="/">
    <table>
      <tr>
        <th>Priority</th>
        <th>Title</th>
        <th>Due date</th>
      </tr>
      <xsl:variable name="results" select="All_Results/Result" />
      <xsl:apply-templates select="$results[1]">
        <xsl:sort select="duedate" />
        <xsl:with-param name="remaining" select="$results[position() > 1]" />
      </xsl:apply-templates>
    </table>
  </xsl:template>

  <xsl:template match="Result">
    <xsl:param name="num" select="1" />
    <xsl:param name="remaining" select="/.." />

    <xsl:variable name="dueDateTick"
                select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string(duedate)))" />
    <xsl:variable name="todayTick"
                select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($Today)))" />

    <xsl:variable name="varOverdue" select="$dueDateTick &lt; $todayTick"
                  ddwrt:cf_explicit="1" />
    <xsl:variable name="varOverduePlus14"
                  select="$dueDateTick &lt; $todayTick +12096000000000"
                  ddwrt:cf_explicit="1" />
    <xsl:variable name="varOverdueToday" select="$dueDateTick = $todayTick"
                  ddwrt:cf_explicit="1"/>

    <xsl:variable name="shouldInclude"
                  select="($ViewType = 'active' and not($varOverdue) 
                           and taskstatus = 'In Progress') or
                          ($ViewType = 'overdue' and $varOverdue and 
                           taskstatus != 'Completed') or
                          ($ViewType = 'upcoming' and taskstatus != 'Completed' and 
                           $varOverduePlus14)" />
    <xsl:apply-templates select="current()[$shouldInclude]"
                         mode="content">
      <xsl:with-param name="varOverdue" select="$varOverdue" />
      <xsl:with-param name="num" select="$num" />
    </xsl:apply-templates>

    <xsl:apply-templates select="$remaining[1]">
      <xsl:with-param name="num" select="$num + $shouldInclude" />
      <xsl:with-param name="remaining" select="$remaining[position() > 1]" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="Result" mode="content">
    <xsl:param name="varOverdue" />
    <xsl:param name="num" />

    <tr>
      <td>
        <xsl:value-of select="priority"/>
      </td>
      <td>
        <a href="{url}" title="{title}">
          You'll need some text here
        </a>
      </td>
      <td>
        <xsl:if test="$num mod 2 = 0">
          <xsl:attribute name="class">ms-alternating ms-itmhover</xsl:attribute>
        </xsl:if>
        <xsl:apply-templates select="current()[$varOverdue]"
                             mode="dueDateStyle" />
        <xsl:value-of select="duedate"/>
      </td>
    </tr>
  </xsl:template>

  <xsl:template match="*" mode="dueDateStyle">
    <xsl:attribute name="style">
      <xsl:text>color: red;</xsl:text>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

我无法对此进行测试,因为我无法访问您正在使用的扩展功能,但请试一试,让我知道它是如何进行的。

于 2013-05-28T07:20:13.567 回答