是否可以按值(即匿名函数/lambda)嵌入函数(构造元素)

Is it possible to embed function (that constructs an element) by value (i.e. anonymous functions/lambdas)

提问人:MrD at KookerellaLtd 提问时间:10/12/2023 最后编辑:MrD at KookerellaLtd 更新时间:10/12/2023 访问量:39

问:

是否可以按值(例如)在映射中嵌入函数,例如

<xsl:function name="kooks:stringAdd" as="xs:string">
    <xsl:param name="s1" as="xs:string"/>
    <xsl:param name="s2" as="xs:string"/>
    <xsl:sequence select="concat($s1,$s2)"/>
</xsl:function>

<xsl:variable name="stringMonoid" as="map(*)">
    <xsl:map>
        <xsl:map-entry key="'zero'" select="''" as="xs:string"/>
        <xsl:map-entry key="'add'" select="kooks:stringAdd#2"/>
    </xsl:map>
</xsl:variable>

我可以像这样写它(在 psuedo xslt 中)吗?

<xsl:variable name="stringMonoid" as="map(*)">
    <xsl:map>
        <xsl:map-entry key="'zero'" select="''" as="xs:string"/>
        <xsl:map-entry key="'add'">
            <xsl:function as="xs:string">
                <xsl:param name="s1" as="xs:string"/>
                <xsl:param name="s2" as="xs:string"/>
                <xsl:sequence select="concat($s1,$s2)"/>
            </xsl:function>
        </xsl:map>
    </xsl:map>
</xsl:variable>

澄清一下,问题是关于 XSLT 函数的,我希望能够构造和返回元素(可悲的是,该示例返回原子类型),虽然您可以嵌入包含内联函数的 xpath 表达式,但我不确定这些表达式是否可以构造元素。

XSLT-3.0 型

评论


答:

0赞 Martin Honnen 10/12/2023 #1

您可以使用匿名函数/lambda 表达式作为键值,例如

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">

  <xsl:output method="xml" indent="yes"/>
  
  <xsl:variable name="stringMonoid" as="map(*)"
    select="map {
             'zero' : '',
             'add' : function($s1 as xs:string, $s2 as xs:string) { $s1 || $s2 }
           }"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="/" name="xsl:initial-template">
    <test>{$stringMonoid?add('This is a ', 'test')}</test>
    <xsl:comment xmlns:saxon="http://saxon.sf.net/">Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} at {current-dateTime()}</xsl:comment>
  </xsl:template>

</xsl:stylesheet>

输出类似(处理器和日期信息会有所不同)

<?xml version="1.0" encoding="UTF-8"?>
<test>This is a test</test>
<!--Run with SAXON HE 10.6 at 2023-10-12T12:13:27.373+02:00-->

使用 SaxonC HE 12.3 的小提琴示例

如果要使用以下命令创建地图,则xsl:map

  <xsl:variable name="stringMonoid" as="map(*)">
    <xsl:map>
      <xsl:map-entry key="'zero'" select="''"/>
      <xsl:map-entry key="'add'" select="function($s1 as xs:string, $s2 as xs:string) { $s1 || $s2 }"/>
    </xsl:map>
  </xsl:variable>

对于匿名函数(诚然,使用 XPath 创建)是可能的。但是我不清楚为什么要使用 XSLT 创建一个匿名函数,如果您的第一个示例有一个定义了命名函数,为什么这还不够?xsl:function

评论

0赞 MrD at KookerellaLtd 10/12/2023
是的,我自己刚刚到达那里,所以你可以在 XPath 中(并将其嵌入到 XSLT 中)但是你能在 XSLT 中做到这一点吗,我觉得编写返回元素之类的 xpath 函数很尴尬
0赞 MrD at KookerellaLtd 10/12/2023
我会将其标记为答案,尽管正如我所说,我宁愿它是在 xslt 而不是 xpath 中。
0赞 MrD at KookerellaLtd 10/12/2023
实际上,您甚至可以编写一个构造新元素的 XPath 表达式吗?所以我删除了这个作为答案,对不起......它确实适用于给定的示例,但我看不到如何使用它来嵌入制作新元素的函数(就像 xslt 函数一样),我没有移动球门柱,而只是更好地定义了它们所在的位置
0赞 Martin Honnen 10/12/2023
@MrDatKookerellaLtd,这当然取决于 XPath,但要直接构造元素或其他节点,您可能需要等待 XPath 4.0 将一些扩展(如 saxonica.com/html/documentation12/functions/saxon/... 作为内置函数库的一部分。function($s as string) { parse-xml-fragment($s) }('<root/>')
0赞 MrD at KookerellaLtd 10/12/2023
啊,好吧。。。因此,对于 XSLT 来说,答案是否定的,但对于 XPath,答案是肯定的。“为什么”只是语法和便利性,我不喜欢 XSLT 的地方是你最终会得到很多很多顶级命名结构(例如函数、模板、变量)等,而实际上它们不需要全局可见,所以嵌入它们,隐藏它们,并将所有内容放在一个地方