Saxon HE Java扩展-如何访问作为参数传递的xsl变量的值?
我使用Saxon文档创建了一个函数,它有3个参数。该函数获取输入字符串,并使用整数和字符串值将其填充到特定大小 padStringLeft(inputStr、大小、padChar) 如果我把它放在XSLT中并硬连接参数,函数就会工作Saxon HE Java扩展-如何访问作为参数传递的xsl变量的值?,java,xslt,saxon,Java,Xslt,Saxon,我使用Saxon文档创建了一个函数,它有3个参数。该函数获取输入字符串,并使用整数和字符串值将其填充到特定大小 padStringLeft(inputStr、大小、padChar) 如果我把它放在XSLT中并硬连接参数,函数就会工作 <debug1><xsl:value-of select="c4j_XSLT_Ext_padStringLeft:padStringLeft('1',4,'0')" /></debug1> 上面的输出将为
<debug1><xsl:value-of select="c4j_XSLT_Ext_padStringLeft:padStringLeft('1',4,'0')" /></debug1>
上面的输出将为“0001”
然而,当我传递XSLT变量的内容并在java函数中设置调试/断点时,我可以看到我将param0作为一个懒散序列
<debug2><xsl:value-of select="c4j_XSLT_Ext_padStringLeft:padStringLeft($myvar,4,'0')" /></debug2>
由于我的代码试图将其视为字符串,因此无法工作
我应该如何处理这个场景,如何访问值或xsl变量/param,如果有时我想使用文本字符串而不是变量,该怎么办
public class XSLT_Ext_padStringLeft extends ExtensionFunctionDefinition
{
@Override
public SequenceType[] getArgumentTypes()
{
return new SequenceType[]{SequenceType.SINGLE_STRING,SequenceType.SINGLE_INTEGER, SequenceType.SINGLE_STRING};
}
@Override
public StructuredQName getFunctionQName()
{
return new StructuredQName("c4j_XSLT_Ext_padStringLeft", "http://com.commander4j.Transformation.XSLT_Ext_padStringLeft", "padStringLeft");
}
@Override
public SequenceType getResultType(SequenceType[] arg0)
{
return SequenceType.SINGLE_STRING;
}
@Override
public ExtensionFunctionCall makeCallExpression()
{
return new ExtensionFunctionCall() {
@Override
public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
String inputStr;
try
{
inputStr = ((StringValue)arguments[0]).getStringValue();
} catch (ClassCastException ex)
{
inputStr = "";
}
long size;
try
{
String temp =arguments[1].toString();
size = Integer.valueOf(temp);
} catch (ClassCastException ex)
{
size = 1;
}
String padStr;
try
{
padStr = ((StringValue)arguments[2]).getStringValue();
} catch (ClassCastException ex)
{
padStr = "";
}
String result = inputStr;
while (result.length() < size)
{
result = padStr + result;
}
return StringValue.makeStringValue(result);
}
};
}
}
公共类XSLT\u Ext\u padStringLeft扩展了扩展函数定义
{
@凌驾
public SequenceType[]getArgumentTypes()
{
返回新的SequenceType[]{SequenceType.SINGLE_STRING,SequenceType.SINGLE_INTEGER,SequenceType.SINGLE_STRING};
}
@凌驾
公共结构QName getFunctionQName()
{
返回新的StructuredQName(“c4j_XSLT_Ext_padStringLeft”http://com.commander4j.Transformation.XSLT_Ext_padStringLeft“,“padStringLeft”);
}
@凌驾
公共SequenceType getResultType(SequenceType[]arg0)
{
返回SequenceType.SINGLE_字符串;
}
@凌驾
公共扩展函数调用makeCallExpression()
{
返回新的ExtensionFunctionCall(){
@凌驾
公共序列调用(XPathContext上下文,序列[]参数)抛出XPathException{
字符串输入str;
尝试
{
inputStr=((StringValue)参数[0])。getStringValue();
}捕获(ClassCastException例外)
{
inputStr=“”;
}
长尺寸;
尝试
{
字符串temp=参数[1]。toString();
大小=整数。值(温度);
}捕获(ClassCastException例外)
{
尺寸=1;
}
字符串padStr;
尝试
{
padStr=((StringValue)参数[2]).getStringValue();
}捕获(ClassCastException例外)
{
padStr=“”;
}
字符串结果=inputStr;
while(result.length()
谢谢
Dave通常,参数作为类
net.sf.saxon.om.Sequence
的实例传递,您应该只使用接口Sequence
上的方法,而不是检查它是哪种类型的Sequence
,因为将来可能会发生变化
如果需要一个单例序列(即单个项),请调用head()
,以获取序列中的第一项(如果序列为空,则返回null)。然后,您将有一个net.sf.saxon.om.Item
的实例。(序列可能已经是一个项
,因为项是一个序列,但您不能依赖它,调用head()
比强制转换更安全。)如果您需要一个字符串,可以安全地调用此项上的getStringValue()
,以获取字符串形式的值
还要注意的是,Saxon尽可能使用惰性求值,这意味着在有人询问字符串的值之前,可能无法实际计算该字符串。这意味着像head()
和getStringValue()
这样看似无辜的调用实际上可以抛出异常,您需要为此做好准备
所以简而言之,你应该替换
inputStr = ((StringValue)arguments[0]).getStringValue();
与
还要注意的是,Saxon尽可能使用惰性求值,这意味着在有人询问字符串的值之前,可能无法实际计算该字符串。这意味着像head()和getStringValue()这样看似无辜的调用实际上可以抛出异常,您需要为此做好准备
因此,如果我理解正确,当我调用Transform来处理XSLT转换时,它将根据需要调用我的每个自定义java外部函数,但
inputStr=参数[0]。head().getStringValue()
是否可以生成异常
然后,我需要在java函数中执行一些操作来强制它获取值,或者让异常传播回调用转换并在那里捕获它
Dave如果您能告诉我们您在哪里声明并将哪个值精确绑定到变量
$myvar
,这会有所帮助。我不得不说,我觉得自己有点不知所措,但我会尽量少问问题。我应该替换所有需要获取参数值的代码,包括引号“literal”参数中的字符串,而不是变量。我的一个参数是一个整数,我的代码似乎就是为了这个。我应该像上面那样修改语法吗?正如您在上面提到的,懒惰的评估可能会触发错误-有没有一个如何处理的示例?有没有关于新的Saxon Library API的培训材料(书籍/视频)?有非常广泛的文档(遗憾的是,对大多数人来说太详细了),但没有这样的培训材料。我的XSLT2.0参考书中有一个附录,但它已经过时了。我是
inputStr = arguments[0].head().getStringValue();