2011-02-07 17 views
2

Javaを使用してXSLT拡張機能で配列を使用しようとしています。Java XSLT拡張機能付き配列

私は以下のエラーを取得しています:私は配列を使用

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

方法です。私はこのためにXALAN解析を使用している拡張クラスメソッドXSL内

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

<?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> 

+0

私は答えは分かりませんが、製品固有のものであることに注意してください。 Xalanで動作するものは、別のXSLTプロセッサでは動作しない可能性があります。拡張機能の動作方法は、XSLT標準やJAXP APIでは定義されていません。 –

+0

私はエラーが明らかだと思います:XPath関数と演算子のデータ型を拡張することはできません。 XSLTとXPathの拡張オブジェクトは、その値を保持して渡すためだけに使用できますが、それらの操作は拡張関数/要素の実装で処理する必要があります。 –

+0

@Alejandro:他の人とこの作品は良いパーサー! – srinannapa

答えて

3

文字列の配列を返すXPath関数を持つことはできません。ただし、作成できるのは、NodeSetを返すXPath XALANの拡張です。あなたの場合、おそらく、テキストノードを含むノードセットが必要です。次に、ノードセットのすべてのノードをループして、拡張ノードセットで生成したすべての文字列を取得します。
私は、私があなたが望むものにできる限り近いソリューションを信じているかを説明するために少しリファクタリングしました。最初のクラスはあなたの拡張です。私が言ったように、それは文字列の配列ではなくノードセットを作成します。 2番目のクラスにはXSLがあります。 EclipseのJavaデバッガ(Eclipse XSLTと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付き)テストクラス。これらの2クラスで

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

} 

、出力はこのスレッドの他のXSLTの要人が指摘したように、このソリューションはXalanのJavaバージョン2.6+にあなたを縛るだろう、

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

..です
1. XSLT 1.0は、拡張機能なしでは役に立たないことがよくあります。
2.各プロセッサには独自の方法(MSXMLのjavascript、XalanのJava、Xalan-Cのエントリポイントが宣言されています...)

関連する問題