Custom NodeList Implementation

I want my own org.w3c.dom.NodeList backed by an ArrayList, so I implemented:

public class SimNodeList extends ArrayList<Node> implements NodeList {

private static final long serialVersionUID = 1L;

public SimNodeList() {

super();

}

public SimNodeList(NodeList nodeList) {

super();

this.add(nodeList);

}

public Node item(int index) {

if (index>=size())

return null;

return get(index);

}

public int getLength() {

return size();

}

public void add(NodeList nodeList) {

if (nodeList==null)

return;

for (int i = 0; i < nodeList.getLength(); i++)

super.add(nodeList.item(i));

}

}

This seems to work ok until I try and use my custom NodeList as the context for another xpath.evaluate:

SimNodeList result1 = new SimNodeList();

result1.add( ..some NodeList... )

SimNodeList result2 = new SimNodeList((NodeList)xpath.evaluate("*", result 1, XPathConstants.NODESET));

If I use anything but "." as the xpath expression I get the following:

javax.xml.transform.TransformerException: Unknown error in XPath.

at com.sun.org.apache.xpath.internal.XPath.execute(Unknown Source)

at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(Unknown Source)

at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)

at org.rje.sim.core.ConfigHelper.getFullOrderedMessageExchangeProcess(ConfigHelper.java:74)

at org.rje.sim.test.ConfigHelperTest.main(ConfigHelperTest.java:41)

Caused by: java.lang.NullPointerException

at com.sun.org.apache.xpath.internal.axes.ChildTestIterator.setRoot(Unknown Source)

at com.sun.org.apache.xpath.internal.axes.NodeSequence.setRoot(Unknown Source)

at com.sun.org.apache.xpath.internal.axes.LocPathIterator.execute(Unknown Source)

... 5 more

java.lang.NullPointerException

at com.sun.org.apache.xpath.internal.axes.ChildTestIterator.setRoot(Unknown Source)

at com.sun.org.apache.xpath.internal.axes.NodeSequence.setRoot(Unknown Source)

at com.sun.org.apache.xpath.internal.axes.LocPathIterator.execute(Unknown Source)

at com.sun.org.apache.xpath.internal.XPath.execute(Unknown Source)

at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(Unknown Source)

at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)

at org.rje.sim.core.ConfigHelper.getFullOrderedMessageExchangeProcess(ConfigHelper.java:74)

at org.rje.sim.test.ConfigHelperTest.main(ConfigHelperTest.java:41)

Process Node List:

linked to

javax.xml.xpath.XPathExpressionException

at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)

at org.rje.sim.core.ConfigHelper.getFullOrderedMessageExchangeProcess(ConfigHelper.java:74)

at org.rje.sim.test.ConfigHelperTest.main(ConfigHelperTest.java:41)

Caused by: javax.xml.transform.TransformerException: Unknown error in XPath.

at com.sun.org.apache.xpath.internal.XPath.execute(Unknown Source)

at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(Unknown Source)

... 3 more

Caused by: java.lang.NullPointerException

at com.sun.org.apache.xpath.internal.axes.ChildTestIterator.setRoot(Unknown Source)

at com.sun.org.apache.xpath.internal.axes.NodeSequence.setRoot(Unknown Source)

at com.sun.org.apache.xpath.internal.axes.LocPathIterator.execute(Unknown Source)

... 5 more

[3557 byte] By [r_jewsona] at [2007-11-26 14:57:35]
# 1

I find that the following applies to the

evaluate(String expression, Object item, QName returnType)

method of the javax.xml.xpath.XPath class:

1. It can only take a Node even though the API documentation says that the "item" parameter can take a "node or node list". In fact, when you pass a NodeList object, it throws a TransformerException as you posted. This behaviour is either a bug or the API documentation is wrong.

2. When you pass a Node to the "item" parameter, the evaluate() method always deals with the root node of its owner document.

3. Interestingly enough, the following expression can be used as a valid parameter value to the "item" parameter:result1.item(-1)

4. It follows from the above points that:

a) The following values are equivalent when passed to the "item" parameter:result1.item(-1)

result1.item(-1).getOwnerDocument()

b) It's no use evaluating a NodeList repeatedly in a way as to use the output of the evaluation for the subsequent evaluation, because each evaluation will process the same list of nodes. (The successive evaluations will not narrow down the initial list of nodes to a smaller one.)

Remark:

You misspelled "result1" as "result 1" in the following line:SimNodeList result2 = new SimNodeList((NodeList)xpath.evaluate("*", result 1, XPathConstants.NODESET));

prgguya at 2007-7-8 8:46:21 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...