Hi, I have a question concerning the Xalan-J Extension mechanism.
I would like to do is return a DocumentFragment or NodeSet from my Extension and in my
xsl iterate through its content.
Exactly what the following example does but the information coming from the extension
function (This example comes from the Xalan-J extension documentation).
<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan">
<xsl:template match="/">
<out>
<xsl:variable name="rtf">
<docelem>
<elem1>
<elem1a>ELEMENT1A</elem1a>
<elem1b>,ELEMENT1B</elem1b>
</elem1>
<elem2>
<elem2a>ELEMENT2A</elem2a>
</elem2>
</docelem> </xsl:variable>
<xsl:for-each select="xalan:nodeset($rtf)/docelem//*">
<xsl:value-of select="name(.)"/><xsl:text>,</xsl:text>
</xsl:for-each>
</out>
</xsl:template></xsl:stylesheet>
The output of running this stylesheet (with any XML input source) is a comma-delimited list of
the element names in the node-set
<out>elem1,elem1a,elem1b,elem2,elem2a</out>
In truth what I need is a list of nodes which I can manipulate as if it were part of the original
xml document.
My extension function's code is as follows:
public NodeIterator getListeIter() {NodeList nl = null;
NodeSet ns = null;
try {
// Same as in the example xsl
String str = "<docelem><elem1><elem1a>ELEMENT1A</elem1a><elem1b>,ELEMENT1B</elem1b></elem1><elem2><elem2a>ELEMENT2A</elem2a></elem2></docelem>";
DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = fact.newDocumentBuilder();Document doc = builder.parse(new ByteArrayInputStream(str.getBytes()));
ns = new NodeSet();
nl = doc.getElementsByTagName("docelem"); // Dumb code to build the nodeSet correctly
for (int x = 0; x < nl.getLength(); x++) {
Node n = nl.item(x);
ns.addNode(n); NodeList nl2 = n.getChildNodes();
for (int y = 0; y < nl2.getLength(); y++) {
Node n2 = nl2.item(y);
ns.addNode(n2); NodeList nl3 = n2.getChildNodes();
for (int z = 0; z < nl3.getLength(); z++) {
Node n3 = nl3.item(z);
ns.addNode(n3); NodeList nl4 = n3.getChildNodes();
for (int a = 0; a < nl4.getLength(); a++) {
Node n4 = nl4.item(a);
ns.addNode(n4);
}
}
}
}
}
catch (Exception e) {
System.out.println("Exception: " + e);
}return ns; }
and my xsl looks like this:
<xsl:variable name="testcies">
<xsl:value-of select="liste-compagnie:getListeIter()"/>
</xsl:variable><xsl:for-each select="xalan:nodeset($testcies)/docelem//*"> // I get a NullPointerException here
<xsl:value-of select="name(.)"/>
</xsl:for-each>
If I omit the call to xalan:nodeset() then I get the following message: Can not convert #RTREEFRAG to a NodeList!
The Xalan Extension document states that when retuning a NodeIterator from an extension function
the result is converted into a XSLT NodeSet so why is the message talking about a TreeFragment.
Any how by using the xalan:nodeset() call I should then have a node set and be able to iterator
over its elements using the <xsl:for-each> element.
I have also tried returning a DocumentFragment however DTM is read only and does not support
the call to context.getContextnode().getOwnerDocument().createDocumentFragment()
Can anyone help me. Does anyone have an example of an extension function returning a DocumentFragment
or NodeSet and xsl source which then iterates over its content.
