/*
* 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());
}
}
}
}