具有JavaXSLT扩展的数组

具有JavaXSLT扩展的数组,java,xslt,Java,Xslt,我正在尝试使用java在XSLT扩展中使用数组 我得到以下错误: Caused by: java.lang.ClassCastException: org.apache.xpath.objects.XObject cannot be cast to org.apache.xpath.objects.XNodeSet. 我使用数组的方式是。一种扩展类方法 public static String[] getEvents(String contractI

我正在尝试使用java在XSLT扩展中使用数组

我得到以下错误:

Caused by: java.lang.ClassCastException: org.apache.xpath.objects.XObject 
                     cannot be cast to org.apache.xpath.objects.XNodeSet.
我使用数组的方式是。一种扩展类方法

public static String[] getEvents(String contractIdStr,String tradeIdStr) {
    return new String[]{"MacroType","Type","SubType"};
}
在XSL内部

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:partyrefrule="com.converter.Rules" 
 exclude-result-prefixes="partyrefrule">

    <xsl:variable name="vLastNegoTradeEvents">
        <xsl:value-of select="partyrefrule:getEvents($cVal,$tVal)"/>
    </xsl:variable>

    <xsl:message terminate="no">
        <xsl:value-of select="$vLastNegoTradeEvents[0]"/>
    </xsl:message>
</xsl:stylesheet>


我使用的是XALAN解析。我认为XPath函数不能返回字符串数组。但是,您可以创建一个XPath XALAN扩展,它返回一个节点集。在本例中,您可能需要一个包含文本节点的节点集。然后,您所要做的就是在节点集的所有节点上循环,以检索在扩展节点集中生成的所有字符串。
我对您的示例进行了一些重构,以说明我认为的解决方案应该尽可能接近您想要的样子。第一节课是你的分机。正如我所说,它创建一个节点集,而不是字符串数组。第二个类具有XSL。这有点神秘,因为为了使用EclipseJava调试器(混合EclipseXSLT和java调试器是不可能的),我需要java中的所有东西(压缩)

好了,首先是分机:

package com.converter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.apache.xalan.extensions.ExpressionContext;
import org.apache.xpath.NodeSet;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XNodeSetForDOM;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class Rules {


    public static XNodeSet getEvents(ExpressionContext context, String s1, String s2) throws TransformerException {

        XNodeSet result = null ;

        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance() ;
            DocumentBuilder dBuilder;
            dBuilder = dbf.newDocumentBuilder();
            Document doc = dBuilder.newDocument();

            NodeSet ns = new NodeSet();

            ns.addNode( doc.createTextNode("MacroType" + s1 ) ) ;
            ns.addNode( doc.createTextNode("Type" + s2 ) ) ;
            ns.addNode( doc.createTextNode("SubType" + s1 + s2 ) ) ;

            result = new XNodeSetForDOM( (NodeList)ns, context.getXPathContext() );

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        return result ;
    }

}
然后是测试类(带有嵌入式XSL)

导入java.io.StringReader;
导入javax.xml.transform.Result;
导入javax.xml.transform.Source;
导入javax.xml.transform.Transformer;
导入javax.xml.transform.TransformerFactory;
导入javax.xml.transform.dom.DOMSource;
导入javax.xml.transform.stream.StreamResult;
导入javax.xml.transform.stream.StreamSource;
公开课考试{
私有静态最终字符串TESTXSL=“”+
" " +
"     " +
"         " +
"             " +
"            , " +
"         " +
"" ;
公共静态void main(字符串[]args)引发异常{
新测试().run();
}
public void run()引发异常{
TransformerFactory transFact=TransformerFactory.newInstance();
Source xsltSource=newstreamsource(newstringreader(TESTXSL));
Transformer xsl=transFact.newTransformer(xsltSource);
Source src=new DOMSource();//仍然未使用
结果结果=新的StreamResult(System.out);
transform(src,result);
}
}
对于这两个类,输出是

<?xml version="1.0" encoding="UTF-8"?>MacroTypes1,Types2,SubTypes1s2
宏类型1、类型2、子类型1s2
同样,正如该线程的其他XSLT VIP所指出的,该解决方案将把您绑定到XalanJavaVersion2.6+。。。但事实是:
1.没有扩展,XSLT1.0通常是无用的。

2.每个处理器都有自己的方式(javascript代表MSXML,java代表Xalan,Xalan-C声明的入口点…)

我不知道答案:但请注意,它是特定于产品的。适用于Xalan的可能不适用于其他XSLT处理器,反之亦然。扩展函数的工作方式既没有在XSLT标准中定义,也没有在JAXP API中定义。我认为错误很明显:不能扩展XPath函数和运算符数据类型。您可以在XSLT和XPath中使用扩展对象来保存和传递它们的值,但是对它们的任何操作都应该由扩展函数/元素实现来处理。@Alejandro:这可以与其他解析器一起使用,很好!你是说其他XSLT处理器吗?
<?xml version="1.0" encoding="UTF-8"?>MacroTypes1,Types2,SubTypes1s2