我想使用我自己的
<xsl:function>
作为 XSLT 3.0 中的分组键。我的函数返回 xs:boolean
,但在分组的输出中,我想将 true
和 false
映射到有意义的字符串值,在我的例子中是 true = 'Live album'
和 false = 'Studio album'
。
我第一次尝试使用 if..else
表达式或将 current-grouping-key()
外包给局部变量,在语法上都失败了。
这是我的样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="https://my-function.library.org" exclude-result-prefixes="#all">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:function name="my:group-key" as="xs:boolean">
<xsl:param name="recording"/>
<xsl:sequence select="contains($recording/title, 'Live')"/>
</xsl:function>
<xsl:template match="/catalog">
<groups>
<xsl:for-each-group select="recording" group-by="my:group-key(.)">
<group key="{current-grouping-key()}">
<xsl:for-each select="current-group()">
<titel><xsl:value-of select="title"/></titel>
</xsl:for-each>
</group>
</xsl:for-each-group>
</groups>
</xsl:template>
</xsl:stylesheet>
这是输入 XML(摘录):
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<recording medium="LP" state="2" no="1">
<title>The Years 1960-1970</title>
(...)
</recording>
<recording medium="tape" state="6" no="2">
<title>Live at the Village Vanguard</title>
(...)
</recording>
<recording medium="CD" state="8" no="3">
<title>Classic Tunes</title>
(...)
</recording>
</catalog>
所需输出:
<?xml version="1.0" encoding="UTF-8"?>
<groups>
<group key="Studio album">
<titel>The Years 1960-1970</titel>
<titel>Classic Tunes</titel>
</group>
<group key="Live album">
<titel>Live at the Village Vanguard</titel>
</group>
</groups>
理想情况下,我希望有一个通用的解决方案,该解决方案将允许更多的映射,而不仅仅是
true
和false
。因此,基于 if..else
的解决方案甚至都不是理想的。
我还想知道将此映射外包给单独的函数是否有意义。也欢迎在这里提出有关最佳实践的任何意见。
我不明白为什么你需要布尔值,为什么不将输入直接映射到输出表单?
<xsl:function name="my:group-key" as="xs:string">
<xsl:param name="recording"/>
<xsl:sequence select="if (contains($recording/title, 'Live'))
then 'Live album'
else 'Studio album'"/>
</xsl:function>