Christian ---

This works fine for me.  I had to put the class in a package because
XalanJ assumes that anything registered without a package name is in its
own functions package.

My output is:

C:\Temp>java foo.FuncHere
Registered class foo.FuncHere for here() function in internal table
FuncHere.execute() has been called
#NODESET
xpath

Gary

Christian Geuer-Pollmann wrote:
> 
> /*
>  * Hi Xalan-Gurus,
>  * dear Gary,
>  *
>  * My extension function crashes (and i programmed some things that I took
>  * from the org.apache.xpath.functions package but did not understood
> completely).
>  *
>  * Could you please have a short (or longer) look at the code and give me
> some advise?
>  *
>  * Regards,
>  * Christian
>  *
>  * @author <mailto:[EMAIL PROTECTED]>
>  */
> 
> import java.io.*;
> import java.util.*;
> import javax.xml.parsers.DocumentBuilder;
> import javax.xml.parsers.DocumentBuilderFactory;
> import org.apache.xalan.extensions.*;
> import org.apache.xalan.templates.*;
> import org.apache.xerces.dom.*;
> import org.apache.xml.utils.*;
> import org.apache.xml.dtm.*;
> import org.apache.xpath.*;
> import org.apache.xpath.objects.*;
> import org.apache.xpath.functions.Function;
> import org.apache.xpath.compiler.FunctionTable;
> import org.apache.xpath.res.XPATHErrorResources;
> import org.w3c.dom.*;
> import org.w3c.dom.traversal.NodeIterator;
> 
> /**
>  * The here function returns a node-set containing the attribute or
>  * processing instruction node or the parent element of the text node
>  * that directly bears the XPath expression.  This expression results
>  * in an error if the containing XPath expression does not appear in the
>  * same XML document against which the XPath expression is being evaluated.
>  *
>  * Mainpart is stolen from FuncId.java
>  *
>  * @see
> http://www.w3.org/Signature/Drafts/xmldsig-core/Overview.html#function-here
>  */
> public class FuncHere extends Function {
> 
>    public XObject execute(XPathContext xctxt)
>            throws javax.xml.transform.TransformerException {
> 
>       System.out.println("FuncHere.execute() has been called");
> 
>       int currentNode = xctxt.getCurrentNode();
>       DTM dtm = xctxt.getDTM(currentNode);
>       int docContext = dtm.getDocument();
> 
>       if (DTM.NULL == docContext) {
>          error(xctxt, XPATHErrorResources.ER_CONTEXT_HAS_NO_OWNERDOC, null);
>       }
> 
>       XNodeSet nodes = new XNodeSet(xctxt.getDTMManager());
>       NodeSetDTM nodeSet = nodes.mutableNodeset();
> 
>       // Do processing here
>       {
>          int contextNode = xctxt.getContextNode();
>          int hereNode;
>          if (dtm.getNodeType(contextNode) == Node.ATTRIBUTE_NODE) {
>             hereNode = contextNode;
>          } else if (dtm.getNodeType(contextNode) ==
> Node.PROCESSING_INSTRUCTION_NODE) {
>             hereNode = contextNode;
>          } else if (dtm.getNodeType(contextNode) == Node.TEXT_NODE) {
>             hereNode = dtm.getParent(contextNode);
>          } else {
>             hereNode = DTM.NULL;
>          }
> 
>          if (DTM.NULL != hereNode) {
>             nodeSet.addNode(hereNode);
>          }
>       }
> 
>       // must I do this detach() ?
>       nodeSet.detach();
>       return nodes;
>    }
> 
>    /**
>     * No arguments to process, so this does nothing.
>     * @param vars
>     * @param globalsSize
>     */
>    public void fixupVariables(java.util.Vector vars, int globalsSize) {}
> 
>    /**
>     * Method main
>     *
>     * @param unused
>     * @throws Exception
>     */
>    public static void main(String unused[]) throws Exception {
> 
>       String thisClass = FuncHere.class.getName();
> 
>       /**
>        * Try to register out here() implementation as internal function.
>        * @todo Is this too much hardcore?
>        */
>       FunctionTable.installFunction("here", new FuncHere());
>       System.out.println("Registered class " + thisClass
>                          + " for here() function in internal table");
> 
>       //J-
>       String input =
>         "<?xml version='1.0' encoding='UTF-8' ?>\n"
>       + "<!DOCTYPE root [\n"
>       + "<!ATTLIST XPath\n"
>       + "          Id      ID      #REQUIRED>\n"
>       + "]>\n"
>       + "<root>\n"
>       + "   <XPath Id='hereInText'>here()</XPath>\n"
>       + "   <XPath Id='hereInAttr' xpath='here()' />\n"
>       + "</root>";
>       //J+
>       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
> 
>       dbf.setNamespaceAware(true);
> 
>       DocumentBuilder db = dbf.newDocumentBuilder();
>       Document doc = db.parse(new ByteArrayInputStream(input.getBytes()));
>       Node a = XPathAPI.selectSingleNode(doc, "/root/XPath[2]");
>       Node attr = ((Element) a).getAttributeNode("xpath");
>       XObject o = XPathAPI.eval(attr, attr.getNodeValue());
> 
>       System.out.println(o.getTypeString());
> 
>       if (o.getType() == XObject.CLASS_NODESET) {
>          NodeIterator ni = o.nodeset();
>          Node currNode;
> 
>          while ((currNode = ni.nextNode()) != null) {
>             System.out.println(currNode.getNodeName());
>          }
>       }
>    }
> }

Reply via email to