使用java XSLT Extensions的数组 [英] Arrays with java XSLT Extensions

查看:206
本文介绍了使用java XSLT Extensions的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用java在XSLT Extensions中使用数组。

I'm trying to use arrays in XSLT Extensions using java .

我收到以下错误:

Caused by: java.lang.ClassCastException: org.apache.xpath.objects.XObject 
                     cannot be cast to org.apache.xpath.objects.XNodeSet.

我使用数组的方式是。扩展类方法

The way I used arrays is. An extension class method

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 Parse。

I'm using XALAN Parse for this.

推荐答案

我认为你不能让一个XPath函数返回一个字符串数组。但是,您可以创建的是返回NodeSet的XPath XALAN扩展。在您的情况下,您可能需要包含文本节点的节点集。然后,您所要做的就是在节点集的所有节点上循环,以检索您在扩展节点集中生成的所有字符串。

我已经重构了一些您举例说明的内容我相信尽可能接近你想要的解决方案应该是这样的。第一堂课是你的扩展。正如我所说,它创建了一个节点集而不是字符串数组。第二类有XSL。这有点神秘,因为我需要在java中拥有一切(紧凑)才能使用eclipse java调试器(混合eclipse XSLT和java调试器是一个非首发)。

I don't think you can have an XPath function returning an array of string. What you can create however is an XPath XALAN extention that returns a NodeSet. In your case, you probably want a node set containing text nodes. Then, all you have to do is loop on all the nodes of your node set to retrieve all the strings you have generated in your extension node-set.
I have refactored a little bit you example to illustrate what I believe a solution as close as possible to what you want should look like. The first class is your extension. As I said, it creates a node set rather than array of strings. The second class has the XSL. It's a little bit cryptic because I needed to have everything (compact) in java in order to use eclipse java debugger (mixing eclipse XSLT and java debuggers is a non starter).

所以在这里你去:首先是扩展名:

So here you go: first the extension:

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

Then the test class (with the embedded XSL).

import java.io.StringReader;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class Test {

    private static final String TESTXSL = "<?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:template match=\"/\"> " +
        "        <xsl:for-each select=\"partyrefrule:getEvents( 's1', 's2' )\"> " +
        "            <xsl:value-of select=\".\"/> " +
        "            <xsl:if test=\"position() != last()\">,</xsl:if> " +
        "        </xsl:for-each></xsl:template> " +
        "</xsl:stylesheet>" ;

    public static void main(String[] args) throws Exception {
        new Test().run () ;
    }

    public void run () throws Exception {
        TransformerFactory transFact = TransformerFactory.newInstance( );
        Source xsltSource = new StreamSource( new StringReader( TESTXSL ) );
        Transformer xsl = transFact.newTransformer(xsltSource);
        Source src = new DOMSource () ; // unused anyway
        Result result = new StreamResult( System.out ) ;
        xsl.transform(src , result );
    }

}

这两个类的输出

<?xml version="1.0" encoding="UTF-8"?>MacroTypes1,Types2,SubTypes1s2

再次,正如这个线程的其他XSLT VIP指出的那样,这个解决方案会将你绑定到Xalan Java版本2.6 + ...但问题的真相是:

1. XSLT 1.0通常无用而无需扩展。

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

Again, as the other XSLT VIPs of this thread have pointed out, this solution will tie you up to Xalan Java version 2.6+... But the truth of the matter is that:
1. XSLT 1.0 is often useless without extensions.
2. each processor has its own way (javascript for MSXML, java for Xalan, declared entry points for Xalan-C...)

这篇关于使用java XSLT Extensions的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆