Closed satyagraha closed 11 years ago
val level3matches = xpathExpr("/level2/level3").xmlPaths(level2).toList
you are still at level2 for that query, where level2 is your new document. If you don't know what the node is that matches but you know which should be below use /*/level3 and skip the root elem.
I very much appreciate the running test case, very easy to see what the intent is.
See #22 for another way
I tried something similar using the underlying Jaxen library (1.1.3) in Java with DomJ, as follows:
package com.test.jaxen;
import java.io.StringReader;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.dom4j.tree.AbstractNode;
import org.jaxen.dom4j.Dom4jXPath;
public class TestJaxen {
private void test() throws Exception {
String xmlText = "<level1 ><level2><level3>contents of level 3</level3><shouldHideChildren><level3>should not see</level3></shouldHideChildren></level2></level1>";
SAXReader reader = new SAXReader();
Document doc = reader.read(new StringReader(xmlText));
Dom4jXPath xpath2 = new Dom4jXPath("/level1/level2");
@SuppressWarnings("unchecked")
List<AbstractNode> level2 = (List<AbstractNode>) xpath2.evaluate(doc);
System.out.println("level2: " + level2 + " size: " + level2.size());
Dom4jXPath xpath3 = new Dom4jXPath("level3");
@SuppressWarnings("unchecked")
List<AbstractNode> level3 = (List<AbstractNode>) xpath3.evaluate(level2);
System.out.println("level3: " + level3 + " size: " + level3.size());
}
public static void main(String[] args) throws Exception {
TestJaxen instance = new TestJaxen();
instance.test();
}
}
Now, that works as I expect, showing values of 1 in each output line. For the scales version, your first proposal works, but it obliges me to add the "/level2/" prefix whereas the native Jaxen one doesn't. If I try the bare "level3" xpath, I get an exception thus:
Exception in thread "main" java.lang.RuntimeException: couldn't get childaxis at scala.sys.package$.error(package.scala:27) at scala.Predef$.error(Predef.scala:123) at scales.utils.package$.error(package.scala:12) at scales.xml.jaxen.ScalesNavigator.getChildAxisIterator(JaxenNavigator.scala:240) at org.jaxen.expr.iter.IterableChildAxis.iterator(IterableChildAxis.java:75) at org.jaxen.expr.DefaultNameStep.evaluate(DefaultNameStep.java:199) at scales.xml.jaxen.ScalesDefaultLocationPath.evaluate(Expr.scala:26) at org.jaxen.expr.DefaultXPathExpr.asList(DefaultXPathExpr.java:102) at scales.xml.jaxen.ScalesBaseJaxenXPath.selectNodesForContext(ScalesBaseJaxenXPath.java:681) at scales.xml.jaxen.ScalesBaseJaxenXPath.selectNodes(ScalesBaseJaxenXPath.java:220) at scales.xml.jaxen.ScalesXPath.evaluate(JaxenNavigator.scala:112) at scales.xml.jaxen.ScalesXPath.xmlPaths(JaxenNavigator.scala:139) at com.test.scales.TestNestedXpath$.test(TestNestedXpath.scala:50) at com.test.scales.TestNestedXpath$.main(TestNestedXpath.scala:58) at com.test.scales.TestNestedXpath.main(TestNestedXpath.scala)
The alternative query "./level3" also raises the same exception. Perhaps you would like to clarify, and thanks for the earlier responses. FYI, this is with Scales 0.4.4 and Jaxen 1.1.3.
As chatted above I raised #22 to cover this, ./level3 etc should work.
Using "level3" directly also works with the fix but seems exceptionally strange to me - auto adding ./, but if its a Jaxen implementation detail (can't find any spec to cover this) then at least Scales will continue to work that way :)
fix in 0.4.5 just released
marking as bug and release, although original not - the / syntax should only go for the root, the developer can use top(tree) to repoint the /, but ./ better explains the intention as well.
Hi there, I am having a bit of trouble when attempting to apply an xpath to the results of a previous xpath. In the code below, I should be able to select the level3 node returned by the first xpath, but no match. If I use // instead, that wrongly picks up both level3 nodes. Thanks for any ideas on this!