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

Posted

技术标签:

【中文标题】Saxon-HE Java 扩展 - 如何访问作为参数传递的 xsl 变量的值?【英文标题】:Saxon-HE Java Extension - How to I access the value of a xsl-variable which is passed as a parameter? 【发布时间】:2021-06-04 02:50:51 【问题描述】:

我使用具有 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,4,'0')" /></debug2>

Java function

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

我应该如何处理这种情况,如何访问值或 xsl 变量/参数,如果有时我想使用文字字符串而不是变量怎么办?

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);
                
            ;
    


谢谢

戴夫

【问题讨论】:

如果您向我们展示您在哪里声明并将哪个值精确绑定到变量$myvar,这将有所帮助。 【参考方案1】:

通常,参数作为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();

【讨论】:

我不得不说我觉得我的深度不够,但我会尽量少问问题。我是否应该替换所有需要获取参数值的代码,包括引号中的字符串“文字”参数而不是变量。我的一个参数是一个整数,我的代码似乎已经为此工作了。我应该修改上面的语法吗?正如您在上面提到的,懒惰的评估可能会引发错误 - 是否有一个如何处理的示例? 是否有关于新撒克逊图书馆 API 的培训材料(书籍/视频)? 有非常广泛的文档(遗憾的是,对大多数人来说太详细了),但没有这样的培训材料。我的 XSLT 2.0 参考书中有一个附录,但它已经过时了。恐怕您处于期望使用 Javadoc 工作的领域。某些东西有效的事实并不意味着您做对了:很容易发现您缺少案例,例如调用者提供了一个空序列。如果您只是让异常以自然方式导致终止,那么错误处理通常不会成为问题。【参考方案2】:

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

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

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

会产生异常吗?

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

戴夫

【讨论】:

以上是关于Saxon-HE Java 扩展 - 如何访问作为参数传递的 xsl 变量的值?的主要内容,如果未能解决你的问题,请参考以下文章

Saxon-HE 集成扩展功能 |如何以及在哪里?

如何在 Saxon-HE 中获得 EXSLT 支持?

如何在 .NET 中使用 Saxon-HE 9.8 使用 XSLT 3.0

XRechnung Visualizer 和 Saxon-HE for .NET 的自闭合 DIV 标签问题

升级 saxon-he-10.5 JAR 后,面临转型问题

Saxon-HE 9.3 的 javax.xml.xpath.XPathFactory 提供程序配置文件中的语法错误