将用户定义函数的结果集传递到max()函数中



如果我不清楚,请第一次发布长时间浏览器。我对xslt很陌生。我正在尝试编写一个函数,该函数将清除日期值的列表传递给max((函数。以下是我的输入文档:

<dates>
<date>1990-09-02Z</date>
<date>1990-09-03Z</date>
<date>1990-09-04Z</date>
<date>1990-09-05Z</date>
<date>1990-09-06Z</date>
</dates>

正如您所看到的,字符串值后面有一个"Z"。如果我尝试使用嵌套的substring((函数将这些直接传递给max((

<xsl:template match="/dates">
<xsl:value-of select="max(xs:date(substring(//date,1,10)))"/>
</xsl:template>

我得到这个错误:

一个以上项目的序列不允许作为fn:substring((("1990-09-02Z","1990-09-03Z"(的第一个参数

所以我在样式表中包含了xsl:function声明,现在它看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:test="http://www.blah.blah/funct"
version="3.0">

<xsl:function name="test:funct" visibility="public">
<xsl:param name="input"/>
<xsl:sequence>  
<xsl:for-each select="$input">
<xsl:value-of select="xs:date(substring(.,1,10))"/>
</xsl:for-each>
</xsl:sequence>
</xsl:function>    

<xsl:template match="/dates">
<xsl:value-of select="max(test:funct(//date))"/>
</xsl:template>

</xsl:stylesheet>

然而,现在我得到以下错误

将{1990-09-02}转换为数字失败

我以为max((可以处理日期?我对传递给max((函数的内容以及它为什么不起作用感到困惑。我想要的输出是1990-09-06

我试着阅读w3org规范文档,但这些条款对我来说太技术性了,所以没有意义。感谢你能提供的任何帮助。

顺便说一下,我使用的处理引擎是Saxon PE 9.8.0.12

edit:我的最终目标是拥有一个带有函数列表的样式表,我可以将这些函数包括在其他xsl样式表中,所以最终的解决方案必须是一个函数。在这种特定的情况下,函数会生成一个清除日期列表,然后将其传递给max((。

由于您已经将其标记为XSLT3,我建议从基本的XPath2/3开始,在那里您可以简单地编写

//date/xs:date(substring(., 1, 10))

即,您可以使用路径的最后一步中的函数调用来提取子字符串并构造xs:date:https://xsltfiddle.liberty-development.net/6rexjii

因此,表达式//date/xs:date(substring(., 1, 10))为您提供了xs:date值的序列,然后您可以对它们使用max函数:

max(//date/xs:date(substring(., 1, 10)))

https://xsltfiddle.liberty-development.net/6rexjii/1

至于编写一个用户定义的函数来完成最后一步,我会编写一个输入为xs:string并返回xs:date:的函数

<xsl:function name="mf:date" as="xs:date">
<xsl:param name="input" as="xs:string"/>
<xsl:sequence select="xs:date(substring($input, 1, 10))"/>
</xsl:function>

然后您可以将其称为max(//date/mf:date(.)):https://xsltfiddle.liberty-development.net/6rexjii/2

如果你真的想写一个函数来处理一系列输入项,以返回一系列xs:date,那么就使用

<xsl:function name="mf:dates" as="xs:date*">
<xsl:param name="input" as="xs:string*"/>
<xsl:sequence select="$input ! xs:date(substring(., 1, 10))"/>
</xsl:function>

并用称之为

<xsl:value-of select="max(mf:dates(//date))"/>

https://xsltfiddle.liberty-development.net/6rexjii/3

作为另一种语法选择,在XPath3.1中,可以使用箭头运算符=>:

<xsl:value-of select="//date => mf:dates() => max()"/>

https://xsltfiddle.liberty-development.net/6rexjii/4

最新更新