我的数据模型如下:
<Club>
<Captain>
<Name></Name>
<DateOfBirth>15-01-1985</DateOfBirth>
</Captain>
<PlayingStaff>
<Player>
<DateOfBirth>14-01-1993</DateOfBirth>
</Player>
<Player>
<DateOfBirth>07-12-1975</DateOfBirth>
</Player>
<Player>
<DateOfBirth>11-11-1991</DateOfBirth>
</Player>
</PlayingStaff>
</Club>
我尝试过使用这里给出的答案:XSLT: Getting the latest date但它并没有给我任何价值。
我正试图让最年轻的玩家转到外部功能。
我在Biztalk中这样做,所以我必须坚持使用XSLT1
到目前为止,我的工作如下:
<xsl:variable name="youngestPlayer">
<xsl:for-each select="$ClubRoot/*[local-name()='PlayingStaff']/*[local-name()='Player']">
<xsl:sort select="./*[local-name()='DateOfBirth']" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="DateOfBirth"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="IsYoungestPlayerUnderAgeLimit" select="externalfunctionreturningboolean">
<xsl:element name="blahhh"><xsl:value-of select="$IsYoungestPlayerUnderAgeLimit"/></xsl:element>
<xsl:element name="blahhh"><xsl:value-of select="$youngestPlayer"/></xsl:element>
这是大型模板的一部分 - 我无法真正改变这一点,但ClubRoot的值是“<xsl:variable name="ClubRoot" select="/*[1]"/>"
,以确保我可以读取它的子节点。”
我总是得到
<blahhh>false</blahhh>
<blahhh/>
作为我的调试值......所以我没有拿到我期望的值
有人可以突出显示我出错的地方吗?
根据上面的数据,我希望我的youngestPlayer变量中的值为14-01-1993。但它的空白。
答案 0 :(得分:7)
问题是XSLT1.0并没有真正的日期概念,所以你有效地按 DateOfBirth 元素进行排序,好像它们只是普通字符串一样。如果您可以确定日期始终采用DD-MM-YYYY格式,您可以使用字符串操作按年,月和日进行排序
<xsl:sort select="number(substring(DateOfBirth, 7, 4))" order="descending"/>
<xsl:sort select="number(substring(DateOfBirth, 3, 2))" order="descending"/>
<xsl:sort select="number(substring(DateOfBirth, 1, 2))" order="descending"/>
因此,给出以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Club">
<xsl:for-each select="PlayingStaff/Player">
<xsl:sort select="number(substring(DateOfBirth, 7, 4))" order="descending"/>
<xsl:sort select="number(substring(DateOfBirth, 3, 2))" order="descending"/>
<xsl:sort select="number(substring(DateOfBirth, 1, 2))" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="DateOfBirth"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
应用于XML时,输出以下内容
14-01-1993
答案 1 :(得分:1)
链接引用中的日期排序“工作”的原因是因为它采用yyyy-MM-dd
格式,而不是dd-MM-yyyy
格式。
Tim C / Sean提议的替代方案是使用C#脚本函数(因为您使用的是BizTalk)根据您的链接将日期恢复为可排序的日期 - 但请注意,这不太可能像本机xslt一样高效功能。另请注意,您可能需要在变量上使用msxsl:node-set来告诉BizTalk的解析器这是一个片段。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="userCSharp msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="ClubRoot" select="/*[1]"/>
<xsl:variable name="orderedPlayers">
<xsl:for-each select="msxsl:node-set($ClubRoot)/*[local-name()='PlayingStaff']/*[local-name()='Player']">
<xsl:sort select="userCSharp:makeSortableDate(string(*[local-name()='DateOfBirth']), 'dd-MM-yyyy')" order="descending"/>
<xsl:copy-of select="node() | @*"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="youngestPlayerDOB">
<xsl:value-of select="msxsl:node-set($orderedPlayers)[1]/DateOfBirth/text()" />
</xsl:variable>
<xsl:element name="blahhh">
<xsl:variable name="IsYoungestPlayerUnderAgeLimit" select="userCSharp:externalfunctionreturningboolean($youngestPlayerDOB)" />
<xsl:value-of select="$IsYoungestPlayerUnderAgeLimit"/>
</xsl:element>
<xsl:element name="blahhh">
<xsl:value-of select="$youngestPlayerDOB"/>
</xsl:element>
</xsl:template>
<msxsl:script language="C#" implements-prefix="userCSharp">
<![CDATA[
public System.String makeSortableDate(System.String yourDate, string format)
{
return (System.DateTime.ParseExact(yourDate, format, System.Globalization.CultureInfo.InvariantCulture).ToString("yyyy-MM-dd"));
}
public bool externalfunctionreturningboolean(System.String dobString)
{
System.DateTime someDate;
if (System.DateTime.TryParse(dobString, out someDate))
{
// NB : Doesn't work out leap years correctly!
if ((System.DateTime.Now - someDate).Days < 21 * 365.25)
{
return true;
}
}
return false;
}
]]>
</msxsl:script>
</xsl:stylesheet>
我对功能进行了攻击并猜测未成年人限制为21.以上回报
<blahhh>true</blahhh>
<blahhh>14-01-1993</blahhh>