Subject: Re: Xalan: result tree fragments / node-set From: Gary L Peskin <garyp@xxxxxxxxxxxx> Date: Thu, 13 Jul 2000 02:02:35 -0700 |
The following code seems to work, although I believe it's partially due to a bug in Xalan. I'll look into in more carefully tomorrow and come up with a solution that will also work when Xalan is fixed. ------------------------------ start of code ------------------------------ package org.apache.xalan.xslt.extensions; import org.w3c.dom.*; import org.apache.xalan.xslt.ResultTreeFrag; import org.apache.xalan.xpath.MutableNodeListImpl; public class Nodeset { /** */ public NodeList nodeset(Node rtf) { DocumentFragment cloneFrag; DocumentFragment retFrag; NodeList fragElementList; int i; if (rtf instanceof DocumentFragment) { cloneFrag = (DocumentFragment) rtf.cloneNode(true); fragElementList = cloneFrag.getChildNodes(); retFrag = cloneFrag.getOwnerDocument().createDocumentFragment(); for (i = 0; i < fragElementList.getLength(); i++) retFrag.appendChild(fragElementList.item(i)); } else { retFrag = rtf.getOwnerDocument().createDocumentFragment(); retFrag.appendChild(rtf.cloneNode(true)); } return new org.apache.xalan.xpath.XNodeSet(retFrag).nodeset(); } } ------------------------------ end of code ------------------------------ To use the code, make your xsl:stylesheet element look like this: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mynodeset="org.apache.xalan.xslt.extensions.Nodeset" extension-element-prefixes="mynodeset" version="1.0"> To invoke the nodeset function, see the following example provided by Juergen Hermann in early posts: XML: <?xml version="1.0"?> <root/> XSL: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mynodeset="org.apache.xalan.xslt.extensions.Nodeset" extension-element-prefixes="mynodeset" version="1.0"> <xsl:output method="xml"/> <xsl:variable name="greeting">abc<h1>Hello, World!</h1>def<xsl:variable> <xsl:template match="root"> Hello, World! <xsl:for-each select="mynodeset:nodeset($greeting)">*<xsl:copy-of select="."/>* </xsl:for-each> </xsl:template> </xsl:stylesheet> Expected Output: Hello, World! *abc<h1>Hello, World!</h1>def* This conforms with the definition of nodeset (note the absence of a hyphen between node and set) given by Mike Kay in his excellent book. The function takes a result tree fragment (RTF) as an argument and returns a node-set consisting of a single node that operates as if it was a root node. The children of the RTF are children of the node returned by this function. As Mike points out, this is not, in general, a well-formed document since the children of the resulting node need not follow the rules for children of a document node. Along the way, I've stumbled across the following observations: 1. I can't write the function in java and call the function "node-set" like xt and saxon because the function has to be the name of a java method and a hyphen is not allowed as the name of a java method. This should be fixed to delete the hyphen if required by the language, I think. 2. Xalan improperly fails to reject the <xsl:copy-of select="."/> when the "node" is an RTF. I don't think you could get this problem working purely in XSLT but an earlier version of my extension function returned a purported nodeset consisting of a single RTF node (actually of type ResultTreeFrag) and the copy-of statement did not complain as it should have. I think this is why my function actually works when it shouldn't. 3. Perhaps the extension mechanism needs to be refined. If I'm writing my extensions in java, it is truly a pain to come up with a new namespace for each java class (ie each extension) unless I just put everything in one class. Perhaps the Xalan extensions (which might someday include node[-]set) should just be in one class. Of course, looking at Redirect, we have instance variables there and it seems silly to have to instantiate them for every extension. Obviously, I haven't thought this out and I haven't looked at BSF but I also don't like having ten different namespaces for ten different extensions. Paul, although I'm new to XSLT and Xalan, I've been programming for quite some time. I'd like to participate in the development effort in any way that would be helpful. I've read the xml.apache.org Get Involved! page and pages linked to that. What do I do next? Gary Paul_Dick@xxxxxxxxx wrote: > > Sukuma asks: > could anyone of the Xalan users drop a few lines of code or give me a > hint how to further process result tree fragments with Xalan? > I'm looking for an equivalent method to xt:node-set()? > > This function is begging to be written. Currently Xalan implements section > 11.1 of the spec and that's all. If you're interested, please contribute. > I > know several people have been asking about it. > > Paul XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: Xalan: result tree fragments / , Juergen Hermann | Thread | Batch XSLT Processing, Meukens, Kris |
Re: XSL FO -> PDF, Sebastian Rahtz | Date | Scanning the directory. Re: Cross-r, Paul Tchistopolskii |
Month |