How can I pass a node as parameter to translets for XSLTC-Processor

View: New views
4 Messages — Rating Filter:   Alert me  

How can I pass a node as parameter to translets for XSLTC-Processor

by Ulrich Heeger :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi everyone,
I have a problem. Previously I had no problem to add a node as parameter to
the XSLT-Processor like:

TransformerFactory tFactory =  TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new StreamSource(xsl));
Document doc =
DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element node = doc.createElement("Root");Element child =
doc.createElement("NAME");
child.appendChild(doc.createTextNode("MyName"));
node.appendChild(child);
transformer.setParameter("Node", node);

In the Stylesheet I could invoke a element-value within this node like:

<xsl:value-of select="$Node/NAME"/>

now I want use translets:

System.getProperties().put("javax.xml.transform.TransformerFactory","org.apa
che.xalan.xsltc.trax.TransformerFactoryImpl");
TransformerFactory tFactory = TransformerFactory.newInstance();
Templates translet = tFactory.newTemplates(new StreamSource(xsl));
Transformer transformer = translet.newTransformer();
transformer.setParameter("Node", node);

When calling the transformation process within my translet I get something
like following exception:

javax.xml.transform.TransformerException: java.lang.RuntimeException: Not
valid conversion from 'org.apache.xerces.dom.ElementImpl' to 'node-set'

Do you know what is wrong?
Which type of class can I use for a node so I can pass it as parameter to a
translet?
I would be very thankful for helpt, greetings,

Ulrich Heeger


Re: How can I pass a node as parameter to translets for XSLTC-Processor

by Henry Zongaro :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi, Ulrich.

"Ulrich Heeger" <heeger@...> wrote on 2007-01-26 05:34:21 AM:
> I have a problem. Previously I had no problem to add a node as parameter
to
> the XSLT-Processor like:
>
> TransformerFactory tFactory =  TransformerFactory.newInstance();
> Transformer transformer = tFactory.newTransformer(new
StreamSource(xsl));
> Document doc =
> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
> Element node = doc.createElement("Root");Element child =
> doc.createElement("NAME");
> child.appendChild(doc.createTextNode("MyName"));
> node.appendChild(child);
> transformer.setParameter("Node", node);

> now I want use translets:
> When calling the transformation process within my translet I get
something
> like following exception:
>
> javax.xml.transform.TransformerException: java.lang.RuntimeException:
Not
> valid conversion from 'org.apache.xerces.dom.ElementImpl' to 'node-set'
>
> Do you know what is wrong?

This is a known limitation of XSLTC.  See, for instance, Jira issue
XALANJ-2057.[1]

One workaround would be to use the document function inside your
stylesheet with a URI of your choosing.  Then install a URIResolver on the
Transformer.  The URIResolver.resolve method should be implemented to look
for that URI and return a DOMSource like the one you've described above.

I hope that helps.

Thanks,

Henry
[1] https://issues.apache.org/jira/browse/XALANJ-2057
------------------------------------------------------------------
Henry Zongaro      XSLT Processors Development
IBM SWS Toronto Lab   T/L 969-6044;  Phone +1 905 413-6044
mailto:zongaro@...


Re: How can I pass a node as parameter to translets for XSLTC-Processor

by amitdk :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Return DTMAxisIterator instead of XNodeSet. That should help solve the issue. Here's the method I use to convert a Document object and pass it as a parameter to the translet.

    private DTMAxisIterator convertDocumentToNodeSet(Document document) throws TransformerException
    {
       
        DOMSource domSource = new DOMSource(document);
        XSLTCDTMManager mgr = new XSLTCDTMManager();
        DTM dtm = mgr.getDTM(domSource, false, null, true, true);
        int dtmRoot = dtm.getDocument();
        DTMAxisIterator iter = dtm.getAxisIterator(Axis.SELF);
        iter.setStartNode(dtmRoot);
       
        return iter;
    }

Re: How can I pass a node as parameter to translets for XSLTC-Processor

by EddyXSL :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi amitdk,

I tried to use your solution to pass a node-set to a translet and I don't understand why, it does not work.
It's very strange but when I navigate in the node-set parameter, I get the nodes of the XML source tree instead ! When I use a debugger, the DTMAxisIterator passed as parameter seems ok, it contains in some deep fields the content of the XML fragment I want to pass as parameter.
But I have to admit that understand how DTMxxx classes work is a real nightmare for me.

Anyway, I don't understand why the official answer to this node-set parameter passing problem is "known issue for XSLTC". When we have a look at the BasisLibrary Xalan class, we can see that the referenceToNodeSet method (called when a parameter is a node-set) exists and does some stuff to get a DTMAxisIterator from either a org.apache.xalan.xsltc.runtime.Node (really don't understand how to get this kind of object) or a DTMAxisIterator by cloning it.
That means for me that the feature is available, am I wrong ?

Thanks for your help,

Eddy

amitdk wrote:
Return DTMAxisIterator instead of XNodeSet. That should help solve the issue. Here's the method I use to convert a Document object and pass it as a parameter to the translet.

    private DTMAxisIterator convertDocumentToNodeSet(Document document) throws TransformerException
    {
       
        DOMSource domSource = new DOMSource(document);
        XSLTCDTMManager mgr = new XSLTCDTMManager();
        DTM dtm = mgr.getDTM(domSource, false, null, true, true);
        int dtmRoot = dtm.getDocument();
        DTMAxisIterator iter = dtm.getAxisIterator(Axis.SELF);
        iter.setStartNode(dtmRoot);
       
        return iter;
    }