我是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))) < ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($Today)))" ddwrt:cf_explicit="1"/>
<xsl:variable name="varOverduePlus14" select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string(duedate))) < 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?
答案 0 :(得分: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 < $todayTick"
ddwrt:cf_explicit="1" />
<xsl:variable name="varOverduePlus14"
select="$dueDateTick < $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>
我无法对此进行测试,因为我无法访问您正在使用的扩展功能,但请尝试一下,让我知道它是怎么回事。