Hi, folks.
Is anybody interested in these tasks?
Or did I do something wrong?
Please someone give me some comments?
--
)Hiroaki Nakamura) [EMAIL PROTECTED]
----- Original Message -----
From: "Hiroaki Nakamura" <[EMAIL PROTECTED]>
To: "Ant Developers List" <[EMAIL PROTECTED]>
Sent: Thursday, January 30, 2003 12:10 PM
Subject: [Proposal] ReadXML, XPathSingle, XPathForEach Task
> Kirk,
> Sorry for my very late response, but shortly after using VPP I came to like
> your idea using XPath. However, I don't need jakarta-digester here personally,
> I think just DOM and XPath are enough. For XPath, Xalan's XPathAPI is very
> handy.
>
> Kirk, Christopher wrote:
> > 1) I have found the real power of Ant+Velocity comes out when Ant is used to
> > load an XML file (that forms the velocity context) and then a set of XPath
> > mappers that specify when Velocity is to be fired and what file is to be
> > generated.
>
> So I made a sample program for proof of concept. Please see an attached patch.
> - First you provide your configuration as a separate xml file,
> like config.xml in the patch.
> - You read the xml with <readxml>, and add the DOM node (newly defined
> <domnode> datatype) to a reference in the ant project (see "init_config"
> target).
> - You can reference a node dom value and set to a property by using
> <xpathsingle> with property attribute (see "xpathsingle_example1" target).
> - You can add a reference by using <xpathsingle> with node attribute
> (see "xpathsingle_example2" target).
> - You can loop on nodes by using <xpathforeach> with node attribute
> (see "xpathforeach_example1" target).
> - You can loop on node values by using <xpathforeach> with property attribute
> (see "xpathforeach_example2" target).
> - "xpathforeach_example3" target is a real life example. It loops on nodes and
> for each loop it calls a task using VPP which references the node value by
> using sample.velocity.XPathTool.
>
> <target name="xpathforeach_example3">
> <xpathforeach node="ear" context="dom1" path="build_config/ears/ear">
> <xpathsingle context="ear" path="@name" property="destdir"/>
> <antcall target="vpp" inheritRefs="true">
> <param name="srcdir" value="."/>
> <param name="destdir" value="${destdir}"/>
> </antcall>
> </xpathforeach>
> </target>
>
> - Also, please see "wrong_example1" and "wrong_example2". It prints the
> same value as the first iteration for each iteration. So you must use
> <antcall> in the loopbody like "xpathforeach_example1".
>
> Usage:
> (1) run ant
> (2) run ant test
> You must run (2) separately since (1) puts a jar file to ant lib directory.
>
> So, what do you all people think about these tasks? I think these are good
> and welcome your feedbacks.
>
> --
> )Hiroaki Nakamura) [EMAIL PROTECTED]
>
>
> diff -ruN XPathForEachSample.orig/application.xml.vpp
> XPathForEachSample/application.xml.vpp
> --- XPathForEachSample.orig/application.xml.vpp 1970-01-01 09:00:00.000000000
> +0900
> +++ XPathForEachSample/application.xml.vpp 2003-01-30 09:52:20.000000000 +0900
> @@ -0,0 +1,23 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +#set($ear = $project.getReference('ear').getNode())
> +
> +<!DOCTYPE application PUBLIC
> + "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
> + "http://java.sun.com/dtd/application_1_3.dtd">
> +
> +<application>
> + <display-name>$xp.value($ear, '@name')</display-name>
> +#foreach($w in $xp.list($ear, 'war'))
> + <module>
> + <web>
> + <web-uri>$xp.value($w, '@filename')</web-uri>
> + <context-root>$xp.value($w, '@context_root')</context-root>
> + </web>
> + </module>
> +#end
> +#foreach($e in $xp.list($ear, 'ejb'))
> + <module>
> + <ejb>$xp.value($e, '@filename')</ejb>
> + </module>
> +#end
> +</application>
> diff -ruN XPathForEachSample.orig/build.xml XPathForEachSample/build.xml
> --- XPathForEachSample.orig/build.xml 1970-01-01 09:00:00.000000000 +0900
> +++ XPathForEachSample/build.xml 2003-01-30 11:30:06.000000000 +0900
> @@ -0,0 +1,134 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +
> +<project name="XPathForEachSample" default="deploy" basedir=".">
> + <property name="ANT_HOME" value="C:/jakarta-ant-1.5.1"/>
> +
> + <target name="compile">
> + <mkdir dir="classes"/>
> + <javac srcdir="src"
> + destdir="classes"
> + debug="true"
> + deprecation="true"
> + optimize="true" >
> + <classpath>
> + <pathelement location="${ANT_HOME}/lib/ant.jar"/>
> + </classpath>
> + </javac>
> + </target>
> +
> + <target name="build" depends="compile">
> + <jar jarfile="mysample.jar" basedir="classes"/>
> + </target>
> +
> + <target name="deploy" depends="build">
> + <copy file="mysample.jar" todir="${ANT_HOME}/lib"/>
> + </target>
> +
> + <target name="init_config">
> + <typedef name="domnode" classname="sample.ant.types.DOMNode"/>
> +
> + <taskdef name="readxml" classname="sample.ant.taskdefs.ReadXML"/>
> + <taskdef name="xpathsingle"
> classname="sample.ant.taskdefs.XPathSingle"/>
> + <taskdef name="xpathforeach"
> classname="sample.ant.taskdefs.XPathForEach"/>
> +
> + <readxml domid="dom1" file="config.xml"/>
> + </target>
> +
> + <target name="test" depends="init_config">
> + <antcall target="xpathsingle_example1" inheritRefs="true"/>
> + <antcall target="xpathsingle_example2" inheritRefs="true"/>
> + <antcall target="xpathforeach_example1" inheritRefs="true"/>
> + <antcall target="xpathforeach_example2" inheritRefs="true"/>
> + <antcall target="xpathforeach_example3" inheritRefs="true"/>
> + <antcall target="wrong_example1" inheritRefs="true"/>
> + <antcall target="wrong_example2" inheritRefs="true"/>
> + </target>
> +
> + <target name="xpathsingle_example1">
> + <xpathsingle context="dom1" path="build_config/ears/ear[1]/@name"
> + property="earname"/>
> + <echo message="earname=${earname}"/>
> + </target>
> +
> + <target name="xpathsingle_example2">
> + <xpathsingle context="dom1" path="build_config/ears/ear[2]" node="ear"/>
> + <xpathsingle context="ear" path="@name" property="earname"/>
> + <echo message="earname=${earname}"/>
> + </target>
> +
> + <target name="xpathforeach_example1">
> + <xpathforeach node="ear" context="dom1" path="build_config/ears/ear">
> + <xpathsingle context="ear" path="@name" property="earname"/>
> + <antcall target="echo_earname"/>
> + </xpathforeach>
> + </target>
> +
> + <target name="echo_earname">
> + <echo message="earname=${earname}"/>
> + </target>
> +
> + <target name="xpathforeach_example2">
> + <xpathforeach property="earname"
> + context="dom1" path="build_config/ears/ear/@name">
> + <antcall target="echo_earname"/>
> + </xpathforeach>
> + </target>
> +
> + <target name="xpathforeach_example3">
> + <xpathforeach node="ear" context="dom1" path="build_config/ears/ear">
> + <xpathsingle context="ear" path="@name" property="destdir"/>
> + <antcall target="vpp" inheritRefs="true">
> + <param name="srcdir" value="."/>
> + <param name="destdir" value="${destdir}"/>
> + </antcall>
> + </xpathforeach>
> + </target>
> +
> + <target name="wrong_example1">
> + <xpathforeach node="ear" context="dom1" path="build_config/ears/ear">
> + <xpathsingle context="ear" path="@name" property="earname"/>
> + <echo message="unchanged_over_iteration -> ${earname}"/>
> + </xpathforeach>
> + </target>
> +
> + <target name="wrong_example2">
> + <xpathforeach property="earname"
> + context="dom1" path="build_config/ears/ear/@name">
> + <echo message="unchanged_over_iteration -> ${earname}"/>
> + </xpathforeach>
> + </target>
> +
> + <target name="vpp">
> + <mkdir dir="${destdir}"
> + description="Creates destdir even if srcdir doesn't exist."/>
> + <available property="vpp_srcdir_exists" file="${srcdir}" type="dir"/>
> + <antcall target="vpp_helper" inheritRefs="true"/>
> + </target>
> + <target name="vpp_helper" if="vpp_srcdir_exists">
> + <mkdir dir="${destdir}"/>
> + <copy todir="${destdir}">
> + <fileset dir="${srcdir}" includes="**/*.vpp"/>
> + <mapper type="glob" from="*.vpp" to="*"/>
> + <filterchain>
> + <filterreader classname="foundrylogic.vpp.VPPFilter">
> + <param type="engine" name="runtime.log" value="vpp.log"/>
> + <param type="class" name="xp" value="sample.velocity.XPathTool"/>
> + </filterreader>
> + </filterchain>
> + </copy>
> + </target>
> +
> + <target name="clean" depends="init_config">
> + <xpathforeach property="earname"
> + context="dom1" path="build_config/ears/ear/@name">
> + <antcall target="delete_ear_dir"/>
> + </xpathforeach>
> + <delete file="vpp.log"/>
> + <delete file="mysample.jar"/>
> + <delete dir="classes"/>
> + </target>
> +
> + <target name="delete_ear_dir">
> + <delete dir="${earname}"/>
> + </target>
> +</project>
> diff -ruN XPathForEachSample.orig/config.xml XPathForEachSample/config.xml
> --- XPathForEachSample.orig/config.xml 1970-01-01 09:00:00.000000000 +0900
> +++ XPathForEachSample/config.xml 2003-01-30 07:18:21.000000000 +0900
> @@ -0,0 +1,20 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +
> +<build_config>
> + <ears>
> + <ear name="ear1" filename="ear1.ear">
> + <war name="war1" filename="war1.war" context_root="/war1"/>
> + <war name="war2" filename="war2.war" context_root="/war2"/>
> + <ejb name="ejb1" filename="ejb1.jar"/>
> + <ejb name="ejb2" filename="ejb2.jar"/>
> + <ejb name="ejb3" filename="ejb3.jar"/>
> + </ear>
> + <ear name="ear2" filename="ear2.ear">
> + <war name="war2" filename="war2.war" context_root="/war2"/>
> + <war name="war3" filename="war3.war" context_root="/war3"/>
> + <ejb name="ejb1" filename="ejb1.jar"/>
> + <ejb name="ejb2" filename="ejb2.jar"/>
> + <ejb name="ejb4" filename="ejb4.jar"/>
> + </ear>
> + </ears>
> +</build_config>
> diff -ruN XPathForEachSample.orig/src/sample/ant/taskdefs/ReadXML.java
> XPathForEachSample/src/sample/ant/taskdefs/ReadXML.java
> --- XPathForEachSample.orig/src/sample/ant/taskdefs/ReadXML.java 1970-01-01
> 09:00:00.000000000 +0900
> +++ XPathForEachSample/src/sample/ant/taskdefs/ReadXML.java 2003-01-30
> 11:07:39.000000000 +0900
> @@ -0,0 +1,59 @@
> +package sample.ant.taskdefs;
> +
> +import java.io.File;
> +import java.io.IOException;
> +
> +import javax.xml.parsers.DocumentBuilder;
> +import javax.xml.parsers.DocumentBuilderFactory;
> +import javax.xml.parsers.ParserConfigurationException;
> +
> +import org.apache.tools.ant.BuildException;
> +import org.apache.tools.ant.Project;
> +import org.apache.tools.ant.Task;
> +import sample.ant.types.DOMNode;
> +import org.w3c.dom.Document;
> +import org.xml.sax.SAXException;
> +
> +/**
> + *
> + */
> +public class ReadXML extends Task {
> + protected String domID;
> + protected File file;
> +
> + public void setDomID(String domID) {
> + this.domID = domID;
> + }
> +
> + public void setFile(File file) {
> + this.file = file;
> + }
> +
> + /**
> + * @see org.apache.tools.ant.Task#execute()
> + */
> + public void execute() throws BuildException {
> + Project prj = getProject();
> + DOMNode dom = (DOMNode)prj.createDataType("domnode");
> + Document doc = parseXML(file);
> + dom.setNode(doc);
> + prj.addReference(domID, dom);
> + }
> +
> + protected Document parseXML(File file) throws BuildException {
> + Document doc = null;
> + try {
> + DocumentBuilderFactory dbf =
> DocumentBuilderFactory.newInstance();
> + DocumentBuilder db = dbf.newDocumentBuilder();
> + doc = db.parse(file);
> + } catch (ParserConfigurationException ex) {
> + throw new BuildException(ex);
> + } catch (IOException ex) {
> + throw new BuildException(ex);
> + } catch (SAXException ex) {
> + throw new BuildException(ex);
> + }
> + return doc;
> + }
> +
> +}
> diff -ruN XPathForEachSample.orig/src/sample/ant/taskdefs/XPathForEach.java
> XPathForEachSample/src/sample/ant/taskdefs/XPathForEach.java
> --- XPathForEachSample.orig/src/sample/ant/taskdefs/XPathForEach.java
> 1970-01-01 09:00:00.000000000 +0900
> +++ XPathForEachSample/src/sample/ant/taskdefs/XPathForEach.java 2003-01-30
> 10:49:20.000000000 +0900
> @@ -0,0 +1,145 @@
> +package sample.ant.taskdefs;
> +
> +import java.util.Enumeration;
> +import java.util.Vector;
> +
> +import org.apache.tools.ant.BuildException;
> +import org.apache.tools.ant.Project;
> +import org.apache.tools.ant.Task;
> +import org.apache.tools.ant.TaskContainer;
> +import sample.ant.types.DOMNode;
> +import sample.ant.util.XPathUtils;
> +import org.w3c.dom.Node;
> +import org.w3c.dom.traversal.NodeIterator;
> +
> +/**
> + *
> + */
> +public class XPathForEach extends Task implements TaskContainer {
> + protected String node;
> + protected String property;
> + protected String context;
> + protected String path;
> +
> + /** Optional Vector holding the nested tasks */
> + private Vector nestedTasks = new Vector();
> +
> + /**
> + * Sets the node.
> + * @param node The node to set
> + */
> + public void setNode(String node) {
> + this.node = node;
> + }
> +
> + /**
> + * Sets the property.
> + * @param property The property to set
> + */
> + public void setProperty(String property) {
> + this.property = property;
> + }
> +
> + /**
> + * Sets the context.
> + * @param context The context to set
> + */
> + public void setContext(String context) {
> + this.context = context;
> + }
> +
> + /**
> + * Sets the path.
> + * @param path The path to set
> + */
> + public void setPath(String path) {
> + this.path = path;
> + }
> +
> + /**
> + * Override [EMAIL PROTECTED] org.apache.tools.ant.Task#maybeConfigure
> + * maybeConfigure} in a way that leaves the nested tasks
> + * unconfigured until they get executed.
> + *
> + * @since Ant 1.5
> + */
> + public void maybeConfigure() throws BuildException {
> + if (isInvalid()) {
> + super.maybeConfigure();
> + } else {
> + getRuntimeConfigurableWrapper().maybeConfigure(getProject(),
> false);
> + }
> + }
> +
> + /**
> + * Add a nested task to Sequential.
> + * <p>
> + * @param nestedTask Nested task to execute Sequential
> + * <p>
> + */
> + public void addTask(Task nestedTask) {
> + nestedTasks.addElement(nestedTask);
> + }
> +
> + /**
> + * Execute all nestedTasks.
> + */
> + public void execute() throws BuildException {
> + if (context == null) {
> + throw new BuildException("context node must be set");
> + }
> + if (path == null) {
> + throw new BuildException("path must be set");
> + }
> + if (property == null && node == null) {
> + throw new BuildException("one of property or node must be set");
> + }
> + if (property != null && node != null) {
> + throw new BuildException("property and node must not be both
> set");
> + }
> +
> + Project prj = getProject();
> + Object savedNodeRef = null;
> + if (node != null) {
> + savedNodeRef = prj.getReference(node);
> + }
> + try {
> + DOMNode contextDOMNode = (DOMNode)prj.getReference(context);
> + if (contextDOMNode == null) {
> + throw new BuildException("context node [" + context + "]
> does not exist.");
> + }
> + Node contextNode = contextDOMNode.getNode();
> +
> + NodeIterator it = XPathUtils.selectNodeIterator(contextNode,
> path);
> + Node n = null;
> + while ((n = it.nextNode()) != null) {
> + if (node != null) {
> + addNewDOMNodeReference(prj, node, n);
> + } else if (property != null) {
> + prj.setProperty(property, n.getNodeValue());
> + }
> +
> + performNestedTasks();
> + }
> + } finally {
> + if (savedNodeRef != null) {
> + prj.addReference(node, savedNodeRef);
> + }
> + }
> + }
> +
> + protected DOMNode addNewDOMNodeReference(Project prj, String id, Node n)
> {
> + DOMNode nDomNode = (DOMNode)prj.createDataType("domnode");
> + nDomNode.setNode(n);
> + prj.addReference(id, nDomNode);
> + return nDomNode;
> + }
> +
> + protected void performNestedTasks()
> + throws BuildException {
> + for (Enumeration e = nestedTasks.elements(); e.hasMoreElements();) {
> + Task nestedTask = (Task) e.nextElement();
> + nestedTask.perform();
> + }
> + }
> +}
> diff -ruN XPathForEachSample.orig/src/sample/ant/taskdefs/XPathSingle.java
> XPathForEachSample/src/sample/ant/taskdefs/XPathSingle.java
> --- XPathForEachSample.orig/src/sample/ant/taskdefs/XPathSingle.java
> 1970-01-01 09:00:00.000000000 +0900
> +++ XPathForEachSample/src/sample/ant/taskdefs/XPathSingle.java 2003-01-30
> 10:49:20.000000000 +0900
> @@ -0,0 +1,92 @@
> +package sample.ant.taskdefs;
> +
> +import org.apache.tools.ant.BuildException;
> +import org.apache.tools.ant.Project;
> +import org.apache.tools.ant.Task;
> +import sample.ant.types.DOMNode;
> +import sample.ant.util.XPathUtils;
> +import org.w3c.dom.Node;
> +
> +/**
> + *
> + */
> +public class XPathSingle extends Task {
> + protected String node;
> + protected String property;
> + protected String context;
> + protected String path;
> +
> + /**
> + * Sets the node.
> + * @param node The node to set
> + */
> + public void setNode(String node) {
> + this.node = node;
> + }
> +
> + /**
> + * Sets the property.
> + * @param property The property to set
> + */
> + public void setProperty(String property) {
> + this.property = property;
> + }
> +
> + /**
> + * Sets the context.
> + * @param context The context to set
> + */
> + public void setContext(String context) {
> + this.context = context;
> + }
> +
> + /**
> + * Sets the path.
> + * @param path The path to set
> + */
> + public void setPath(String path) {
> + this.path = path;
> + }
> +
> + /**
> + * @see org.apache.tools.ant.Task#execute()
> + */
> + public void execute() throws BuildException {
> + if (context == null) {
> + throw new BuildException("context node must be set");
> + }
> + if (path == null) {
> + throw new BuildException("path must be set");
> + }
> + if (property == null && node == null) {
> + throw new BuildException("one of property or node must be set");
> + }
> + if (property != null && node != null) {
> + throw new BuildException("property and node must not be both
> set");
> + }
> +
> + Project prj = getProject();
> + DOMNode contextDOMNode = (DOMNode)prj.getReference(context);
> + if (contextDOMNode == null) {
> + throw new BuildException("context node [" + context + "] does
> not exist.");
> + }
> + Node contextNode = contextDOMNode.getNode();
> + Node n = XPathUtils.selectSingleNode(contextNode, path);
> + if (n == null) {
> + throw new BuildException("exaclty one node must be selected by
> xpath");
> + }
> +
> + if (node != null) {
> + addNewDOMNodeReference(prj, node, n);
> + } else if (property != null) {
> + prj.setProperty(property, n.getNodeValue());
> + }
> + }
> +
> + protected DOMNode addNewDOMNodeReference(Project prj, String id, Node n)
> {
> + DOMNode nDomNode = (DOMNode)prj.createDataType("domnode");
> + nDomNode.setNode(n);
> + prj.addReference(id, nDomNode);
> + return nDomNode;
> + }
> +}
> diff -ruN XPathForEachSample.orig/src/sample/ant/types/DOMNode.java
> XPathForEachSample/src/sample/ant/types/DOMNode.java
> --- XPathForEachSample.orig/src/sample/ant/types/DOMNode.java 1970-01-01
> 09:00:00.000000000 +0900
> +++ XPathForEachSample/src/sample/ant/types/DOMNode.java 2003-01-30
> 10:49:48.000000000 +0900
> @@ -0,0 +1,16 @@
> +package sample.ant.types;
> +
> +import org.apache.tools.ant.types.DataType;
> +import org.w3c.dom.Node;
> +
> +public class DOMNode extends DataType {
> + protected Node node;
> +
> + public void setNode(Node node) {
> + this.node = node;
> + }
> +
> + public Node getNode() {
> + return node;
> + }
> +}
> diff -ruN XPathForEachSample.orig/src/sample/ant/util/XPathUtils.java
> XPathForEachSample/src/sample/ant/util/XPathUtils.java
> --- XPathForEachSample.orig/src/sample/ant/util/XPathUtils.java 1970-01-01
> 09:00:00.000000000 +0900
> +++ XPathForEachSample/src/sample/ant/util/XPathUtils.java 2003-01-30
> 10:48:49.000000000 +0900
> @@ -0,0 +1,32 @@
> +package sample.ant.util;
> +
> +import javax.xml.transform.TransformerException;
> +
> +import org.apache.tools.ant.BuildException;
> +import org.apache.xpath.XPathAPI;
> +import org.w3c.dom.Node;
> +import org.w3c.dom.traversal.NodeIterator;
> +
> +/**
> + *
> + */
> +public class XPathUtils {
> + public static Node selectSingleNode(Node contextNode, String path)
> + throws BuildException {
> + try {
> + return XPathAPI.selectSingleNode(contextNode, path);
> + } catch (TransformerException ex) {
> + throw new BuildException(ex);
> + }
> + }
> +
> + public static NodeIterator selectNodeIterator(Node contextNode, String
> path)
> + throws BuildException {
> + try {
> + return XPathAPI.selectNodeIterator(contextNode, path);
> + } catch (TransformerException ex) {
> + throw new BuildException(ex);
> + }
> + }
> +
> +}
> diff -ruN XPathForEachSample.orig/src/sample/velocity/XPathTool.java
> XPathForEachSample/src/sample/velocity/XPathTool.java
> --- XPathForEachSample.orig/src/sample/velocity/XPathTool.java 1970-01-01
> 09:00:00.000000000 +0900
> +++ XPathForEachSample/src/sample/velocity/XPathTool.java 2003-01-30
> 10:48:29.000000000 +0900
> @@ -0,0 +1,251 @@
> +package sample.velocity;
> +
> +import java.util.ArrayList;
> +import java.util.Iterator;
> +import java.util.List;
> +
> +import javax.xml.transform.TransformerException;
> +
> +import org.apache.xml.utils.PrefixResolver;
> +import org.apache.xpath.XPathAPI;
> +import org.apache.xpath.objects.XObject;
> +import org.w3c.dom.Node;
> +import org.w3c.dom.NodeList;
> +import org.w3c.dom.traversal.NodeIterator;
> +
> +/**
> + *
> + */
> +public class XPathTool {
> + public XPathTool() {
> + }
> +
> + public String value(Node contextNode, String str)
> + throws TransformerException {
> + Node n = node(contextNode, str);
> + return n == null ? null : n.getNodeValue();
> + }
> +
> + public String value(Node contextNode, String str, Node namespaceNode)
> + throws TransformerException {
> + Node n = node(contextNode, str, namespaceNode);
> + return n == null ? null : n.getNodeValue();
> + }
> +
> + /**
> + * Use an XPath string to select a single node. XPath namespace
> + * prefixes are resolved from the context node, which may not
> + * be what you want (see the next method).
> + *
> + * @param str A valid XPath string.
> + * @return The first node found that matches the XPath, or null.
> + *
> + * @throws TransformerException
> + */
> + public Node node(Node contextNode, String str)
> + throws TransformerException {
> + return XPathAPI.selectSingleNode(contextNode, str);
> + }
> +
> + /**
> + * Use an XPath string to select a single node. XPath namespace
> + * prefixes are resolved from the context node, which may not
> + * be what you want (see the next method).
> + *
> + * @param str A valid XPath string.
> + * @return The first node found that matches the XPath, or null.
> + *
> + * @throws TransformerException
> + */
> + public Node node(Node contextNode, String str, Node namespaceNode)
> + throws TransformerException {
> + return XPathAPI.selectSingleNode(contextNode, str, namespaceNode);
> + }
> +
> + public Iterator iter(Node contextNode, String str)
> + throws TransformerException {
> + return asIterator(nodeIter(contextNode, str));
> + }
> +
> + public Iterator iter(Node contextNode, String str, Node namespaceNode)
> + throws TransformerException {
> + return asIterator(nodeIter(contextNode, str, namespaceNode));
> + }
> +
> + /**
> + * Use an XPath string to select a nodelist.
> + * XPath namespace prefixes are resolved from the contextNode.
> + *
> + * @param str A valid XPath string.
> + * @return A NodeIterator, should never be null.
> + *
> + * @throws TransformerException
> + */
> + public NodeIterator nodeIter(Node contextNode, String str)
> + throws TransformerException {
> + return XPathAPI.selectNodeIterator(contextNode, str);
> + }
> +
> + /**
> + * Use an XPath string to select a nodelist.
> + * XPath namespace prefixes are resolved from the contextNode.
> + *
> + * @param str A valid XPath string.
> + * @return A NodeIterator, should never be null.
> + *
> + * @throws TransformerException
> + */
> + public NodeIterator nodeIter(Node contextNode, String str, Node
> namespaceNode)
> + throws TransformerException {
> + return XPathAPI.selectNodeIterator(contextNode, str, namespaceNode);
> + }
> +
> + public List list(Node contextNode, String str)
> + throws TransformerException {
> + return asList(nodeList(contextNode, str));
> + }
> +
> + public List list(Node contextNode, String str, Node namespaceNode)
> + throws TransformerException {
> + return asList(nodeList(contextNode, str, namespaceNode));
> + }
> +
> + /**
> + * Use an XPath string to select a nodelist.
> + * XPath namespace prefixes are resolved from the contextNode.
> + *
> + * @param str A valid XPath string.
> + * @return A NodeIterator, should never be null.
> + *
> + * @throws TransformerException
> + */
> + public NodeList nodeList(Node contextNode, String str)
> + throws TransformerException {
> + return XPathAPI.selectNodeList(contextNode, str);
> + }
> +
> + /**
> + * Use an XPath string to select a nodelist.
> + * XPath namespace prefixes are resolved from the contextNode.
> + *
> + * @param str A valid XPath string.
> + * @return A NodeIterator, should never be null.
> + *
> + * @throws TransformerException
> + */
> + public NodeList nodeList(Node contextNode, String str, Node
> namespaceNode)
> + throws TransformerException {
> + return XPathAPI.selectNodeList(contextNode, str, namespaceNode);
> + }
> +
> + /**
> + * Evaluate XPath string to an XObject. Using this method,
> + * XPath namespace prefixes will be resolved from the namespaceNode.
> + * @param str A valid XPath string.
> + * @return An XObject, which can be used to obtain a string, number,
> nodelist, etc, should never be null.
> + * @see org.apache.xpath.objects.XObject
> + * @see org.apache.xpath.objects.XNull
> + * @see org.apache.xpath.objects.XBoolean
> + * @see org.apache.xpath.objects.XNumber
> + * @see org.apache.xpath.objects.XString
> + * @see org.apache.xpath.objects.XRTreeFrag
> + *
> + * @throws TransformerException
> + */
> + public XObject eval(Node contextNode, String str)
> + throws TransformerException {
> + return XPathAPI.eval(contextNode, str);
> + }
> +
> + /**
> + * Evaluate XPath string to an XObject. Using this method,
> + * XPath namespace prefixes will be resolved from the namespaceNode.
> + * @param str A valid XPath string.
> + * @return An XObject, which can be used to obtain a string, number,
> nodelist, etc, should never be null.
> + * @see org.apache.xpath.objects.XObject
> + * @see org.apache.xpath.objects.XNull
> + * @see org.apache.xpath.objects.XBoolean
> + * @see org.apache.xpath.objects.XNumber
> + * @see org.apache.xpath.objects.XString
> + * @see org.apache.xpath.objects.XRTreeFrag
> + *
> + * @throws TransformerException
> + */
> + public XObject eval(Node contextNode, String str, Node namespaceNode)
> + throws TransformerException {
> + return XPathAPI.eval(contextNode, str, namespaceNode);
> + }
> +
> + /**
> + * Evaluate XPath string to an XObject.
> + * XPath namespace prefixes are resolved from the namespaceNode.
> + * The implementation of this is a little slow, since it creates
> + * a number of objects each time it is called. This could be optimized
> + * to keep the same objects around, but then thread-safety issues
> would arise.
> + *
> + * @param contextNode The node to start searching from.
> + * @param str A valid XPath string.
> + * @param namespaceNode The node from which prefixes in the XPath will
> be resolved to namespaces.
> + * @param prefixResolver Will be called if the parser encounters
> namespace
> + * prefixes, to resolve the prefixes to URLs.
> + * @return An XObject, which can be used to obtain a string, number,
> nodelist, etc, should never be null.
> + * @see org.apache.xpath.objects.XObject
> + * @see org.apache.xpath.objects.XNull
> + * @see org.apache.xpath.objects.XBoolean
> + * @see org.apache.xpath.objects.XNumber
> + * @see org.apache.xpath.objects.XString
> + * @see org.apache.xpath.objects.XRTreeFrag
> + *
> + * @throws TransformerException
> + */
> + public XObject eval(
> + Node contextNode,
> + String str,
> + PrefixResolver prefixResolver)
> + throws TransformerException {
> + return XPathAPI.eval(contextNode, str, prefixResolver);
> + }
> +
> +
> + protected Iterator asIterator(NodeIterator nit) {
> +// List list = new ArrayList();
> +// Node n = null;
> +// while ((n = nit.nextNode()) != null) {
> +// list.add(n);
> +// }
> +// return list.iterator();
> + final NodeIterator fnit = nit;
> + return new Iterator() {
> + protected Object savedNext;
> +
> + public boolean hasNext() {
> + if (savedNext == null) {
> + savedNext = fnit.nextNode();
> + }
> + return savedNext != null;
> + }
> + public Object next() {
> + if (savedNext == null) {
> + return fnit.nextNode();
> + } else {
> + Object n = savedNext;
> + savedNext = null;
> + return n;
> + }
> + }
> + public void remove() {
> + throw new UnsupportedOperationException();
> + }
> + };
> + }
> +
> + protected List asList(NodeList nl) {
> + int len = nl.getLength();
> + List list = new ArrayList(len);
> + for (int i = 0; i < len; i++) {
> + list.add(nl.item(i));
> + }
> + return list;
> + }
> +
> +}
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
>