这个问题具体是关于在XSLT 2.0和Saxon中使用XPath。
[1]
对于像
这样的XPathfollowing-sibling::foo[1]
descendant::bar[1]
我认为Saxon不会在整个轴上进行迭代,但在找到第一个匹配节点时停止 - 在以下情况下至关重要:
following-sibling::foo[some:expensivePredicate(.)][1]
我认为这样的XPath也是如此:
(following-sibling::foo/descendant::bar)[1]
即。在选择集合中的第一个节点之前,Saxon不会编译匹配following-sibling::foo/descendant::bar
的整个节点集。相反,它(即使对于链式轴)也会停在第一个匹配节点上。
[last()]
现在它变得有趣了。什么时候去"倒退"在树中,我假设XPath喜欢
preceding-sibling::foo[1]
与其following-sibling
等价物一样有效。但是当链接轴时会发生什么,例如
(preceding-sibling::foo/descendant::bar)[last()]
我们需要在此使用[last()]
代替[1]
,
last()
的数值吗?preceding-sibling
轴?descendant
轴以更有效地找到最后一个后代?答案 0 :(得分:1)
Saxon有各种评估package additiveprimes;
import java.util.Arrays;
import java.util.Scanner;
/**
*
* @author talarik048
*/
public class AdditivePrimes {
public static void main(String[] args){
AdditivePrimes additivePrime = new AdditivePrimes();
additivePrime.userInput(x);
additivePrime.isPrime(x);
additivePrime.numArray(x);
}
public void userInput(String x){
Scanner sc = new Scanner(System.in);
try{
System.out.println("Please enter a number: ");
x = sc.nextLine();
} catch(NumberFormatException e){
System.out.println("Error, try again: ");
x = sc.nextLine();
}
}
public void isPrime(String x){
this.userInput(x);
boolean prime = true;
int y = Integer.parseInt(x);
for(int i = 0; i < y; i++){
if(y % i == 0){
prime = false;
break;
}
if(prime){
System.out.println("Your number is prime...");
} else {
System.out.println("Your number is not prime...");
}
}
}
public void numArray(String x){
this.userInput(x);
String[] strArray = x.split("\\s+");
boolean prime = true;
int[] numbArray = new int[strArray.length];
for(int j = 0; j < strArray.length; j++){
try{
numbArray[j] = Integer.parseInt(strArray[j]);
} catch(NumberFormatException e){
System.out.println("ERROR");
}
for(int i = 0; i < numbArray.length; i++){
int sum = (Arrays.stream(numbArray).sum());
if(sum % i == 0){
prime = false;
break;
}
if(prime){
System.out.println("Your number is an additive prime...");
} else {
System.out.println("Your number is not an additive prime...");
}
}
}
}
}
的策略。当用作谓词时,意味着last()
,它通常被转换为内部函数[position()=last()]
,可以通过单项预测进行评估。 (所以在你的[isLast()]
示例中,它并没有在内存中构建节点集,而是逐个读取节点,当它到达结尾时,返回它找到的最后一个节点集)。
在其他情况下,特别是在XSLT匹配模式中使用时,Saxon会将(preceding-sibling::foo /descendant::bar)[last()]
转换为child::x[last()]
。
当这些方法都不起作用时,多年来,Saxon根据应用的表达式有两种评估child::x[not(following-sibling::x)]
的策略:(a)有时它会对表达式进行两次评估,第一次计算节点和第二次归还他们; (b)在其他情况下,它会将所有节点读入内存。我们最近遇到了策略(a)失败的情况:请参阅https://saxonica.plan.io/issues/3122,因此我们一直在做(b)。
last()
表达式可能很昂贵,应该尽可能避免。例如,经典&#34;在相邻的项目之间插入一个分隔符&#34;这通常是写的
last()
更好地写成
xx
if (position() != last()) sep
即。而不是在除了最后一项之外的每个项之后插入分隔符,而是在除第一项之外的每个项之前插入它或者使用if (position() != 1) sep
xx
或string-join
。