Saxon-HE Java 扩展 - 如何访问作为参数传递的 xsl 变量的值?

问题描述

我使用具有 3 个参数的 Saxon 文档创建了一个函数。该函数接受一个输入字符串并使用整数和字符串值将其填充到特定大小。

padStringLeft(inputStr,size,padChar)

如果我把它放在我的 XSLT 中并硬连线参数,函数就可以工作了。

<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,'0')" /></debug2>

Java function

由于我的代码试图将其视为字符串,因此它不起作用。

我应该如何处理这种情况,如何访问值或 xsl-variable/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);
                }
            };
    }

}

谢谢

戴夫

解决方法

一般来说,参数是作为类net.sf.saxon.om.Sequence的实例传递的,你应该只使用接口Sequence上的方法,而不是检查它是什么特定类型的Sequence ,因为这可能会在未来发生变化。

如果您需要单例序列(即单个项目),请调用 head() 以获取序列中的第一个项目(如果序列为空,这将返回 null)。然后,您将拥有一个 net.sf.saxon.om.Item 实例。 (Sequence 可能已经是 Item,因为项目是一个序列,但您不能依赖它,并且调用 head() 比强制转换更安全。)如果您需要一个字符串,您可以安全地在此项上调用 getStringValue() 以获取字符串形式的值。

另外请注意,Saxon 尽可能使用惰性求值,这意味着在有人询问它的值之前,该字符串可能实际上不会被计算。这意味着像 head()getStringValue() 这样看似无辜的调用实际上可以抛出异常,您需要为此做好准备。

总之,你应该更换

inputStr = ((StringValue)arguments[0]).getStringValue();

inputStr = arguments[0].head().getStringValue();
,

另外请注意,Saxon 尽可能使用惰性求值,这意味着在有人询问它的值之前,该字符串可能实际上不会被计算。这意味着像 head() 和 getStringValue() 这样看似无辜的调用实际上可以抛出异常,您需要为此做好准备。

所以如果我理解正确的话——当我调用 Transform 来处理 XSLT 转换时,它会根据需要调用我的每个自定义 java 外部函数,但引用

inputStr = arguments[0].head().getStringValue();

会产生异常吗?

然后我需要在 java 函数中做一些事情来强制它获取值 - 或者我会让异常传播回调用转换并在那里捕获它?

戴夫

相关问答

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