与 XPath 表达式相比,非流模式下的 XSLT 3 累加器是否提供性能优势?

问题描述

假设我有一个这样的文档:

df.show()
#+----------+----+
#|      Date|name|
#+----------+----+
#|12/12/2020|   a|
#|24/01/2019|   b|
#|12/24/2020|   d|
#|       nan|   e|
#+----------+----+

from pyspark.sql.functions import *

df.withColumn("output",to_date(col('Date'),'dd/MM/yyyy')).\
filter(col("output").isNotNull()).\
show()
#+----------+----+----------+
#|      Date|name|    output|
#+----------+----+----------+
#|12/12/2020|   a|2020-12-12|
#|24/01/2019|   b|2019-01-24|
#+----------+----+----------+

#without adding new column
df.filter(to_date(col('Date'),'dd/MM/yyyy').isNotNull()).show()
#+----------+----+
#|      Date|name|
#+----------+----+
#|12/12/2020|   a|
#|24/01/2019|   b|
#+----------+----+

我想找到列表中最年轻的人。

看来我可以用一个普通的 XPath 表达式(类似于 <persons> <person age="14" name="John"/> <person age="23" name="Rob"/> ... </persons> )来做到这一点。在 XSLT 3 中,我还可以编写这样的累加器:

//person[@age=min(//person/@age)]

然后在需要时调用 <xsl:accumulator name="acc" initial-value="()"> <xsl:accumulator-rule match="person" select="if(@age &lt; $value/@age) then . else $value"/> </xsl:accumulator>

在非流媒体环境中,使用一种比另一种更好吗?我认为,至少,使用累加器可以使我免于编写可能效率低下的 XPath 表达式。或者,一个复杂的 XPath 处理器(在我的例子中是 Saxon)是否会将查询优化为等效于使用累加器,因此我如何做并不重要?

解决方法

在累加器可能比常规 XPath 表达式更快的情况下,您需要为文档中的许多节点计算某个值(例如,节号或年初至今的总数),并且节点 N 的值可以方便地表示为较早节点的值的函数。 xsl:number 是一个经典案例。但是您也可以使用 XSLT 3.0 备忘录函数来实现这一点。

如果您的 XPath 表达式使用前面的轴,那么这是一个信号,表示累加器可能会有所帮助。

,

到目前为止我能想到的最“有创意”的使用没有流的累加器是在尝试使用 XPath 3.1 函数 random-number-generator 时,使用 ?next() 函数有点棘手如果你想为树中的某些节点处理它,累加器可以很容易,例如:

  <xsl:accumulator name="random-number" as="map(*)" initial-value="random-number-generator(current-dateTime())">
    <xsl:accumulator-rule match="*" select="$value?next()"/>
  </xsl:accumulator>

并将其用作例如

  <xsl:template match="*">
    <xsl:comment select="accumulator-before('random-number')?number"/>
    <xsl:next-match/>
  </xsl:template>

那种不需要单个值但需要为树中某些匹配节点计算值的处理,其中下一个节点的值取决于前一个节点的值是使用累加器而不使用流的类型其中单个 XPath 表达式可能更难,或者如果不使用累加器,您将需要在 XSLT 2 或 3 中使用隧道参数。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...