Apparently the reason I was so ready to agree this was a bug that should be fixed is that I already fixed it as http://issues.apache.org/jira/browse/JXPATH-128 . So since you're already experienced with building JXPath now you should be able to build from svn trunk and give that a whirl.
-Matt --- On Wed, 3/4/09, Matt Benson <gudnabr...@yahoo.com> wrote: > From: Matt Benson <gudnabr...@yahoo.com> > Subject: Re: JXPath over Generic Collection<?>, How? > To: "Commons Users List" <user@commons.apache.org> > Date: Wednesday, March 4, 2009, 7:57 AM > > Hi Andrew, > I agree that going through the list of properties > should avoid the explicit "class" check problem (I think > this is because you are using LazyDynaBeans instead of > "regular" DynaBeans). As for returning all matches vs. > the first match, rather than selectValue(...) you need to > selectNodes(...), or iterate(...). There are other > useful methods, e.g. those dealing with pointers, also > available on JXPathContext. > > So as for your bug, yes it can/should be fixed, but you > might also consider whether you can use non-lazy DynaBeans > instead. > > Regards, > Matt > > --- On Tue, 3/3/09, Andrew Hughes <ahhug...@gmail.com> > wrote: > > > From: Andrew Hughes <ahhug...@gmail.com> > > Subject: Re: JXPath over Generic Collection<?>, > How? > > To: "Commons Users List" <user@commons.apache.org> > > Date: Tuesday, March 3, 2009, 5:37 PM > > For efficiency reasons I can see why > > you are using String[] here and not > > List.add()... > > Anyway, I have a fix (sort of) for this bug. The > number of > > names needs to be > > calculated a little differently to what it currently > is... > > > > public String[] getPropertyNames() { > > /* @todo do something about the > > sorting - LIKE WHAT? - MJB */ > > if (names == null) { > > DynaClass > > dynaClass = dynaBean.getDynaClass(); > > DynaProperty[] > > properties = dynaClass.getDynaProperties(); > > int count = > > properties.length; > > boolean hasClass > > = dynaClass.getDynaProperty("class") != null; > > > > //count the > > number of property names we have > > count = 0; > > for (int i = 0; i > > < properties.length; i++) { > > > > String name = properties[i].getName(); > > if > > (!hasClass || !name.equals("class")) { > > > > count++; //it's only a property is it's not a > > class and > > doesn't just have a class property. > > } > > } > > //read the > > property names into a String[] to return > > names = new > > String[count]; > > for (int i = 0, j > > = 0; i < properties.length; i++) { > > > > String name = properties[i].getName(); > > if > > (!hasClass || !name.equals("class")) { > > > > names[j++] = name; > > } > > } > > > > Arrays.sort(names); > > } > > return names; > > } > > > > Now I can sort of sucessfully run all my expressions, > > yippee!! However, I > > now have a problem with multiple deep results. Queries > like > > //dog/* I would > > expect to return all "dog's"[] but this just returns > the > > first one it finds. > > Maybe this is asking a little too much of JXPath and > > child/node > > step-up/step-down traversal? Matt can probably tell me > if > > this is or is not > > the case pleeeease :) > > > > > > > > > > > > On Wed, Mar 4, 2009 at 9:38 AM, Andrew Hughes <ahhug...@gmail.com> > > wrote: > > > > > Pretty sure this is a bug in JXPath - and it is > not > > tested by the current > > > unit tests. > > > I can't quite work out 100% of what's going on > here... > > but it has to do > > > with gathering the property names from a > DynaBean > > child member of a (parent) > > > DynaBean. Especially, when it try's to deal with > the > > property named 'name' > > > and 'class'. > > > > > > The problem with query '//dog' etc's > > 'ArrayOutOfBoundsException 0' occurs > > > below. And rightfully so, names[] is a zero > length > > array and for some > > > reason JXPath is trying to set a value for the > first > > entry of a zero length > > > array. That aint ever going to work! But why > is > > the array length zero? > > > Because the properties.length==1, however the > > 'hasClass==true' and it's > > > count-- then negates the correct count calculated > from > > properties.length. I > > > think the problem is in the hasClass > calculation... > > 'boolean hasClass = > > > dynaClass.getDynaProperty("class") != null;' > or > > the conditional 'if' > > > statement. I don't understand the JXPath logic > here > > completely, but I know > > > it doesn't deal with the way I am using it and I > > genuinely feel this is a > > > bug we can fix :'( > > > > > > > > > public String[] > > getPropertyNames() { > > > /* @todo do > > something about the sorting - LIKE WHAT? - MJB */ > > > if (names == > > null) { > > > > > DynaClass dynaClass = > > dynaBean.getDynaClass(); > > > > > DynaProperty[] properties = > > dynaClass.getDynaProperties(); > > > //returns one property 'name=root' (correct) > > > > > int count = properties.length; > > //returns/set's '1' (correct) > > > > > boolean hasClass = > > dynaClass.getDynaProperty("class") != null; > > > //returns/sets 'true' (?unknown?) > > > if > > (hasClass) { //this is true and executes > > > > > count--; // > > Exclude "class" from properties > > > } > > > > > names = new String[count]; //names is a > > zero length array..... > > > WRONG!!! I do have at least 1 property called > > 'name'!!!! > > > > > for (int i = 0, j = 0; i < > > properties.length; i++) { > > > > > String name = properties[i].getName(); > > > > > if (!hasClass || !name.equals("class")) { > > > > > names[j++] = name; //it breaks > > here > > > ArrayOutOfBoundsException 0!!!!! WRONG :'( > > > > > } > > > } > > > > > Arrays.sort(names); > > > } > > > return names; > > > } > > > > > > > > > > > > > > > On Fri, Feb 27, 2009 at 10:02 AM, Andrew Hughes > <ahhug...@gmail.com>wrote: > > > > > >> Thanks again Matt, good to hear that it's > working > > at your end :) At my end > > >> JXPath's DynaBeanPropertyPointer seems to get > into > > problems > > >> with ArraIndexOutOfBounds exceptions on the > > PropertyNames of my DynaBean (see > > >> the strack trace below) with many of the > queries. > > I can only speculate > > >> why this might be... and I won't speculate > > publically. I'm running the code > > >> with JXPath 1.3, BeanUtils 1.8.0, and Java > > 1.6_u11 (within eclipse 3.4). The > > >> code I'm trying to run is pasted below > > VERBATIM.... if that works on your > > >> environment and not mine then it must be a > > compatibility/platform problem. > > >> You've helped me out heaps so far Matt but > can I > > please ask you to > > >> copy/paste the VERBATIM code and test? > > >> > > >> 2009-02-27 08:43:59,940 ERROR (Main.java:89) > > [runEvaluation] Failed to > > >> evaluate /root/animal/cat/tiger[last()] > > >> > > >> java.lang.ArrayIndexOutOfBoundsException: 0 > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.dynabeans.DynaBeanPropertyPointer.getPropertyNames(DynaBeanPropertyPointer.java:84) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.prepareForIndividualProperty(PropertyIterator.java:270) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPositionIndividualProperty(PropertyIterator.java:154) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPosition(PropertyIterator.java:139) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.setPosition(ChildContext.java:101) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.nextNode(ChildContext.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:340) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:339) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:339) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.PredicateContext.nextSet(PredicateContext.java:174) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.getSingleNodePointer(EvalContext.java:311) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.searchForPath(Path.java:201) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.getSingleNodePointerForSteps(Path.java:176) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.LocationPath.computeValue(LocationPath.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:353) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:313) > > >> > > >> at rnd.Main.runEvaluation(Main.java:68) > > >> > > >> at rnd.Main.main(Main.java:56) > > >> > > >> 2009-02-27 08:43:59,956 INFO > (Main.java:66) > > [runEvaluation] About to > > >> evaulate the expression: /root/animal/dog/* > > >> > > >> 2009-02-27 08:43:59,956 ERROR (Main.java:89) > > [runEvaluation] Failed to > > >> evaluate /root/animal/dog/* > > >> > > >> java.lang.ArrayIndexOutOfBoundsException: 0 > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.dynabeans.DynaBeanPropertyPointer.getPropertyNames(DynaBeanPropertyPointer.java:84) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.prepareForIndividualProperty(PropertyIterator.java:270) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPositionIndividualProperty(PropertyIterator.java:154) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPosition(PropertyIterator.java:139) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.setPosition(ChildContext.java:101) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.nextNode(ChildContext.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:340) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:339) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:339) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.getSingleNodePointer(ChildContext.java:70) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.searchForPath(Path.java:201) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.getSingleNodePointerForSteps(Path.java:176) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.LocationPath.computeValue(LocationPath.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:353) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:313) > > >> > > >> at rnd.Main.runEvaluation(Main.java:68) > > >> > > >> at rnd.Main.main(Main.java:57) > > >> > > >> 2009-02-27 08:43:59,956 INFO > (Main.java:66) > > [runEvaluation] About to > > >> evaulate the expression: //dog > > >> > > >> 2009-02-27 08:43:59,956 ERROR (Main.java:89) > > [runEvaluation] Failed to > > >> evaluate //dog > > >> > > >> java.lang.ArrayIndexOutOfBoundsException: 0 > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.dynabeans.DynaBeanPropertyPointer.getPropertyNames(DynaBeanPropertyPointer.java:84) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.prepareForIndividualProperty(PropertyIterator.java:270) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.getNodePointer(PropertyIterator.java:106) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.getSingleNodePointer(ChildContext.java:76) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.searchForPath(Path.java:201) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.getSingleNodePointerForSteps(Path.java:176) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.LocationPath.computeValue(LocationPath.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:353) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:313) > > >> > > >> at rnd.Main.runEvaluation(Main.java:68) > > >> > > >> at rnd.Main.main(Main.java:58) > > >> > > >> 2009-02-27 08:43:59,956 INFO > (Main.java:66) > > [runEvaluation] About to > > >> evaulate the expression: //dog/* > > >> > > >> 2009-02-27 08:43:59,956 ERROR (Main.java:89) > > [runEvaluation] Failed to > > >> evaluate //dog/* > > >> > > >> java.lang.ArrayIndexOutOfBoundsException: 0 > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.dynabeans.DynaBeanPropertyPointer.getPropertyNames(DynaBeanPropertyPointer.java:84) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.prepareForIndividualProperty(PropertyIterator.java:270) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPositionIndividualProperty(PropertyIterator.java:154) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPosition(PropertyIterator.java:139) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.setPosition(ChildContext.java:101) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.nextNode(ChildContext.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:340) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.getSingleNodePointer(ChildContext.java:70) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.searchForPath(Path.java:201) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.getSingleNodePointerForSteps(Path.java:176) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.LocationPath.computeValue(LocationPath.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:353) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:313) > > >> > > >> at rnd.Main.runEvaluation(Main.java:68) > > >> > > >> at rnd.Main.main(Main.java:59) > > >> > > >> 2009-02-27 08:43:59,956 INFO > (Main.java:66) > > [runEvaluation] About to > > >> evaulate the expression: > > //cat/*[objectName='LION'] > > >> > > >> 2009-02-27 08:43:59,956 ERROR (Main.java:89) > > [runEvaluation] Failed to > > >> evaluate //cat/*[objectName='LION'] > > >> > > >> java.lang.ArrayIndexOutOfBoundsException: 0 > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.dynabeans.DynaBeanPropertyPointer.getPropertyNames(DynaBeanPropertyPointer.java:84) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.prepareForIndividualProperty(PropertyIterator.java:270) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPositionIndividualProperty(PropertyIterator.java:154) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPosition(PropertyIterator.java:139) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.setPosition(ChildContext.java:101) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.ChildContext.nextNode(ChildContext.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:340) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.axes.PredicateContext.nextSet(PredicateContext.java:174) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.EvalContext.getSingleNodePointer(EvalContext.java:311) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.searchForPath(Path.java:201) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.Path.getSingleNodePointerForSteps(Path.java:176) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.compiler.LocationPath.computeValue(LocationPath.java:87) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:353) > > >> > > >> at > > >> > > > org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:313) > > >> > > >> at rnd.Main.runEvaluation(Main.java:68) > > >> > > >> at rnd.Main.main(Main.java:60) > > >> > > >> > > >> > > >> > > >> My Code VERBATIM > > >> > > >> package rnd; > > >> > > >> import java.util.ArrayList; > > >> > > >> import > org.apache.commons.beanutils.LazyDynaBean; > > >> import > org.apache.commons.jxpath.JXPathContext; > > >> import org.apache.log4j.Logger; > > >> > > >> public class Main { > > >> > > >> private static final Logger log = > > Logger.getLogger(Main.class); > > >> > > >> public static void main(String[] args) { > > >> log.info("Starting..."); > > >> LazyDynaBean lazyDynaBean = new > > LazyDynaBean(); //the transparent root. > > >> LazyDynaBean root = new LazyDynaBean(); > > >> LazyDynaBean animal = new LazyDynaBean(); > > >> LazyDynaBean dog = new LazyDynaBean(); > > >> LazyDynaBean cat = new LazyDynaBean(); > > >> LazyDynaBean boxer = new LazyDynaBean(); > > >> LazyDynaBean labrador = new > LazyDynaBean(); > > >> LazyDynaBean tiger1 = new LazyDynaBean(); > > >> LazyDynaBean tiger2 = new LazyDynaBean(); > > >> LazyDynaBean tiger3 = new LazyDynaBean(); > > >> LazyDynaBean lion = new LazyDynaBean(); > > >> //set the @objectName property of each > bean, > > user UPPER to make them > > >> distinct for examples. > > >> root.set("objectName","ROOT"); > > >> animal.set("objectName","ANIMAL"); > > >> dog.set("objectName","DOG"); > > >> cat.set("objectName","CAT"); > > >> boxer.set("objectName","BOXER"); > > >> labrador.set("objectName","LABRADOR"); > > >> tiger1.set("objectName","TIGER-ONE"); > > >> tiger2.set("objectName","TIGER-TWO"); > > >> tiger3.set("objectName","TIGER-THREE"); > > >> lion.set("objectName","LION"); > > >> //build the bean hierarchy. > > >> lazyDynaBean.set("root",0, root); > > >> root.set("animal",0, animal); > > >> animal.set("dog",0,dog); > > >> animal.set("cat",0,cat); > > >> dog.set("labrador",0,labrador); > > >> dog.set("boxer",0, boxer); > > >> cat.set("tiger",0,tiger1);//duplicate > > >> cat.set("tiger",1,tiger2);//duplicate > > >> cat.set("tiger",2,tiger3);//duplicate > > >> cat.set("lion",0,lion); > > >> > > >> > > JXPathContext context = > > JXPathContext.newContext(lazyDynaBean); > > >> > > >> //these all > > work > > >> > > runEvaluation("/root/animal/dog", > > context); //absolute & single > > >> > > runEvaluation("/root/animal/cat/tiger[2]", > > context); //absolute & > > >> single > > >> > > runEvaluation("/root/animal/cat/tiger", > > context); //absolute & > > >> multiple > > >> //everything > > below fails > > >> > > runEvaluation("/root/animal/cat/tiger[last()]", > > context); > > >> //absolute & single > > >> > > runEvaluation("/root/animal/dog/*", > > context); //absolute & > > >> multiple > > >> > > runEvaluation("//dog", context); //deep > > search > > >> > > runEvaluation("//dog/*", context);//deep > > multiple > > >> > > runEvaluation("//cat/*[objectName='LION']", > > context);//deep filter > > >> > > >> } > > >> > > >> > > >> public static void runEvaluation(String > > expression,JXPathContext > > >> context){ > > >> log.info("About to evaulate the > expression: > > "+expression); > > >> try { > > >> Object value = context.getValue(expression); > > >> //we got a single result. > > >> if (value instanceof LazyDynaBean) { > > >> LazyDynaBean r = > > (LazyDynaBean)context.getValue(expression); > > >> log.info("Ran '" + expression + "' and got > > objectName='" + > > >> r.get("objectName") + "'"); > > >> > > >> } > > >> //we got multiple results > > >> else if (value instanceof ArrayList) { > > >> String titles = ""; > > >> for (LazyDynaBean bean : > > ((ArrayList<LazyDynaBean>) value )){ > > >> titles += (bean.get("objectName")+","); > > >> } > > >> log.info("Ran " + expression + " and got > > "+((ArrayList)value).size()+" > > >> results: "+titles); > > >> } > > >> //we got a non-dyna bean. > > >> else { > > >> log.info("Ran '" + expression + "' and got > a > > class '" + > > >> value.getClass().getName() + "' with > toString() '" > > +value.toString() + "'"); > > >> } > > >> } catch (Exception e) { > > >> // TODO Auto-generated catch block > > >> log.error("Failed to evaluate > > "+expression,e); > > >> } > > >> } > > >> } > > >> > > >> > > >> > > >> > > >> On Fri, Feb 27, 2009 at 3:56 AM, Matt Benson > > <gudnabr...@yahoo.com>wrote: > > >> > > >>> > > >>> Those paths work for me. Maybe > something > > else is going awry? > > >>> > > >>> -Matt > > >>> > > >>> --- On Thu, 2/26/09, Andrew Hughes <ahhug...@gmail.com> > > wrote: > > >>> > > >>> > From: Andrew Hughes <ahhug...@gmail.com> > > >>> > Subject: Re: JXPath over Generic > > Collection<?>, How? > > >>> > To: "Commons Users List" <user@commons.apache.org> > > >>> > Date: Thursday, February 26, 2009, > 12:53 > > AM > > >>> > Many queries don't work, I > > >>> > can't get any results for the > following > > (code > > >>> > taken from previous email)... > > >>> > > > >>> > > > runEvaluation("/root/animal/cat/tiger[last()]", > context); > > >>> > //absolute > > >>> > & single > > >>> > > > >>> > runEvaluation("/root/animal/dog/*", > > context); //absolute > > >>> > & multiple > > >>> > > > runEvaluation("//dog", > > >>> > context); //deep search > > >>> > > > runEvaluation("//dog/*", > > >>> > context);//deep multiple > > >>> > > > >>> > > > runEvaluation("//cat/*[objectName='LION']", > context);//deep > > >>> > filter > > >>> > > > >>> > These are the really interesting > benefits > > on xpath that I > > >>> > would dearly like > > >>> > to have. > > >>> > > > >>> > A Huge Thanks once again for your > reply > > Matt!!! :) > > >>> > > > >>> > > > >>> > > > >>> > On Thu, Feb 26, 2009 at 10:55 AM, > Matt > > Benson <gudnabr...@yahoo.com> > > >>> > wrote: > > >>> > > > >>> > > > > >>> > > How so? If you simply treat > > the name property as > > >>> > an element rather than an > > >>> > > attribute, you're done, no? > > >>> > > > > >>> > > -Matt > > >>> > > > > >>> > > --- On Wed, 2/25/09, Andrew > Hughes > > <ahhug...@gmail.com> > > >>> > wrote: > > >>> > > > > >>> > > > From: Andrew Hughes <ahhug...@gmail.com> > > >>> > > > Subject: Re: JXPath over > > Generic > > >>> > Collection<?>, How? > > >>> > > > To: "Commons Users List" > <user@commons.apache.org> > > >>> > > > Date: Wednesday, February > 25, > > 2009, 6:22 PM > > >>> > > > Indeed Matt, you are > correct > > and I do > > >>> > > > apologize... but I must > say I > > find > > >>> > > > your emailed explanation > much > > better. Kudos & > > >>> > Thanks! > > >>> > > > I'll (finally) get a > chance to > > work on this > > >>> > tomorrow, but I > > >>> > > > think I am still > > >>> > > > stuck :'( > > >>> > > > > > >>> > > > > > >>> > > > Cheers for everything so > > far!!!! > > >>> > > > > > >>> > > > > > >>> > > > On Tue, Feb 24, 2009 at > 1:43 > > PM, Matt Benson > > >>> > <gudnabr...@yahoo.com> > > >>> > > > wrote: > > >>> > > > > > >>> > > > > > > >>> > > > > I won't get to look > at > > this again at least > > >>> > before > > >>> > > > tomorrow (9PM for me now > > >>> > > > > and still have some > > late-night $work to look > > >>> > at), but > > >>> > > > I thought I would > > >>> > > > > mention straight off > that > > the @name feature > > >>> > actually > > >>> > > > IS mentioned in the > > >>> > > > > userguide under the > > section about working > > >>> > with > > >>> > > > (java.util.)Maps. If > you > > >>> > > > > have a suggestion of > where > > in the guide > > >>> > would be > > >>> > > > another good place to > > >>> > > > > mention it as a > caveat > > and/or even the > > >>> > wording to use, > > >>> > > > feel free to open a > > >>> > > > > documentation issue > in > > JIRA for it. > > >>> > > > > > > >>> > > > > TBC, > > >>> > > > > Matt > > >>> > > > > > > >>> > > > > --- On Mon, 2/23/09, > > Andrew Hughes <ahhug...@gmail.com> > > >>> > > > wrote: > > >>> > > > > > > >>> > > > > > From: Andrew > Hughes > > <ahhug...@gmail.com> > > >>> > > > > > Subject: Re: > JXPath > > over Generic > > >>> > > > Collection<?>, How? > > >>> > > > > > To: "Commons > Users > > List" <user@commons.apache.org> > > >>> > > > > > Date: Monday, > > February 23, 2009, 6:24 > > >>> > PM > > >>> > > > > > Hi Matt, > > >>> > > > > > Thanks HEAPS for > you > > reply, I am really > > >>> > really > > >>> > > > really > > >>> > > > > > grateful. I > think > > that > > >>> > > > > > I have > progressed > > just a little with > > >>> > this but > > >>> > > > there are > > >>> > > > > > still some BIG > > >>> > > > > > shortfalls with > this. > > I've attached > > >>> > code that > > >>> > > > should run > > >>> > > > > > out the box and > is > > >>> > > > > > based on > previous > > emails. If I can get > > >>> > the > > >>> > > > expressions > > >>> > > > > > below to > correctly > > >>> > > > > > evaluate I would > be > > heaps happy. > > >>> > > > > > > > >>> > > > > > Thanks heaps > again, > > hopefully this will > > >>> > work soon > > >>> > > > enough. > > >>> > > > > > > > >>> > > > > > p.s. I can > understand > > the 'name' vs > > >>> > '@name', > > >>> > > > perhaps the > > >>> > > > > > userguide could > > >>> > > > > > mention this is > about > > all I can add. > > >>> > > > > > > > >>> > > > > > > > >>> > > > > > code... > > >>> > > > > > > > >>> > > > > > package rnd; > > >>> > > > > > > > >>> > > > > > import > > java.util.ArrayList; > > >>> > > > > > > > >>> > > > > > import > > >>> > > > > > org.apache.commons.beanutils.LazyDynaBean; > > >>> > > > > > import > > >>> > > org.apache.commons.jxpath.JXPathContext; > > >>> > > > > > import > > org.apache.log4j.Logger; > > >>> > > > > > > > >>> > > > > > public class > Main { > > >>> > > > > > > > >>> > > > > > private static > final > > Logger log = > > >>> > > > > > > > Logger.getLogger(Main.class); > > >>> > > > > > > > >>> > > > > > public static > void > > main(String[] args) > > >>> > { > > >>> > > > > > > > log.info("Starting..."); > > >>> > > > > > LazyDynaBean > > lazyDynaBean = new > > >>> > LazyDynaBean(); > > >>> > > > //the > > >>> > > > > > transparent > root. > > >>> > > > > > LazyDynaBean > root = > > new > > >>> > LazyDynaBean(); > > >>> > > > > > LazyDynaBean > animal = > > new > > >>> > LazyDynaBean(); > > >>> > > > > > LazyDynaBean dog > = > > new LazyDynaBean(); > > >>> > > > > > LazyDynaBean cat > = > > new LazyDynaBean(); > > >>> > > > > > LazyDynaBean > boxer = > > new > > >>> > LazyDynaBean(); > > >>> > > > > > LazyDynaBean > labrador > > = new > > >>> > LazyDynaBean(); > > >>> > > > > > LazyDynaBean > tiger1 = > > new > > >>> > LazyDynaBean(); > > >>> > > > > > LazyDynaBean > tiger2 = > > new > > >>> > LazyDynaBean(); > > >>> > > > > > LazyDynaBean > tiger3 = > > new > > >>> > LazyDynaBean(); > > >>> > > > > > LazyDynaBean > lion = > > new > > >>> > LazyDynaBean(); > > >>> > > > > > //set the > @objectName > > property of each > > >>> > bean, user > > >>> > > > UPPER to > > >>> > > > > > make them > > >>> > > > > > distinct for > > examples. > > >>> > > > > > > > root.set("objectName","ROOT"); > > >>> > > > > > > > animal.set("objectName","ANIMAL"); > > >>> > > > > > > > dog.set("objectName","DOG"); > > >>> > > > > > > > cat.set("objectName","CAT"); > > >>> > > > > > > > boxer.set("objectName","BOXER"); > > >>> > > > > > > > labrador.set("objectName","LABRADOR"); > > >>> > > > > > > > tiger1.set("objectName","TIGER-ONE"); > > >>> > > > > > > > tiger2.set("objectName","TIGER-TWO"); > > >>> > > > > > > > >>> > > tiger3.set("objectName","TIGER-THREE"); > > >>> > > > > > > > lion.set("objectName","LION"); > > >>> > > > > > //build the > bean > > hierarchy. > > >>> > > > > > > > lazyDynaBean.set("root",0, root); > > >>> > > > > > > root.set("animal",0, > > animal); > > >>> > > > > > > > animal.set("dog",0,dog); > > >>> > > > > > > > animal.set("cat",0,cat); > > >>> > > > > > > > dog.set("labrador",0,labrador); > > >>> > > > > > > dog.set("boxer",0, > > boxer); > > >>> > > > > > > > cat.set("tiger",0,tiger1);//duplicate > > >>> > > > > > > > cat.set("tiger",1,tiger2);//duplicate > > >>> > > > > > > > cat.set("tiger",2,tiger3);//duplicate > > >>> > > > > > > > cat.set("lion",0,lion); > > >>> > > > > > > > >>> > > > JXPathContext > > context = > > >>> > > > > > > > >>> > > JXPathContext.newContext(lazyDynaBean); > > >>> > > > > > > > >>> > > > > > > > >>> > //these all > > >>> > > > work > > >>> > > > > > > > >>> > > > > > > > runEvaluation("/root/animal/dog", > > >>> > context); > > >>> > > > //absolute & > > >>> > > > > > single > > >>> > > > > > > > >>> > > > > > > > >>> > > > runEvaluation("/root/animal/cat/tiger[2]", > > >>> > > > context); > > >>> > > > > > //absolute > & > > >>> > > > > > single > > >>> > > > > > > > >>> > > > > > > > runEvaluation("/root/animal/cat/tiger", > > >>> > context); > > >>> > > > //absolute > > >>> > > > > > & > > >>> > > > > > multiple > > >>> > > > > > > > >>> > > > //everything below > > fails > > >>> > > > > > > > >>> > > > > > > > >>> > > > runEvaluation("/root/animal/cat/tiger[last()]", > > >>> > > > context); > > >>> > > > > > //absolute > > >>> > > > > > & single > > >>> > > > > > > > >>> > > > > > > > runEvaluation("/root/animal/dog/*", > > >>> > context); > > >>> > > > //absolute > > >>> > > > > > & multiple > > >>> > > > > > > > >>> > > > > > runEvaluation("//dog", > > >>> > > > > > context); > //deep > > search > > >>> > > > > > > > >>> > > > > > runEvaluation("//dog/*", > > >>> > > > > > context);//deep > > multiple > > >>> > > > > > > > >>> > > > > > > > >>> > > > runEvaluation("//cat/*[objectName='LION']", > > >>> > > > context);//deep > > >>> > > > > > filter > > >>> > > > > > > > >>> > > > > > } > > >>> > > > > > public static > > void > > >>> > runEvaluation(String > > >>> > > > > > > > expression,JXPathContext context){ > > >>> > > > > > log.info("About > to > > evaulate the > > >>> > expression: > > >>> > > > "+expression); > > >>> > > > > > > > >>> > try { > > >>> > > > > > Object value = > > >>> > context.getValue(expression); > > >>> > > > > > //we got a > single > > result. > > >>> > > > > > if (value > instanceof > > LazyDynaBean) { > > >>> > > > > > LazyDynaBean r > = > > >>> > > > > > > > >>> > > > (LazyDynaBean)context.getValue(expression); > > >>> > > > > > log.info("Ran '" > + > > expression + "' and > > >>> > got > > >>> > > > objectName='" + > > >>> > > > > > > r.get("objectName") + > > "'"); > > >>> > > > > > } > > >>> > > > > > //we got > multiple > > results > > >>> > > > > > else if (value > > instanceof ArrayList) { > > >>> > > > > > String titles = > ""; > > >>> > > > > > for > (LazyDynaBean > > bean : > > >>> > > > > > ((ArrayList<LazyDynaBean>) > > >>> > > > > > value )){ > > >>> > > > > > titles += > > >>> > (bean.get("objectName")+","); > > >>> > > > > > } > > >>> > > > > > log.info("Ran " > + > > expression + " and > > >>> > got > > >>> > > > > > > > "+((ArrayList)value).size()+" > > >>> > > > > > results: > "+titles); > > >>> > > > > > } > > >>> > > > > > //we got a > non-dyna > > bean. > > >>> > > > > > else { > > >>> > > > > > log.info("Ran '" > + > > expression + "' and > > >>> > got a > > >>> > > > class '" + > > >>> > > > > > > > value.getClass().getName() + "' with > > >>> > toString() > > >>> > > > '" > > >>> > > > > > > +value.toString() + > > "'"); > > >>> > > > > > } > > >>> > > > > > } catch > (Exception e) > > { > > >>> > > > > > log.error(e); > > >>> > > > > > } > > >>> > > > > > } > > >>> > > > > > } > > >>> > > > > > > > >>> > > > > > > > >>> > > > > > > > >>> > > > > > > > >>> > > > > > > > >>> > > > > > On Tue, Feb 24, > 2009 > > at 8:58 AM, Matt > > >>> > Benson > > >>> > > > <gudnabr...@yahoo.com> > > >>> > > > > > wrote: > > >>> > > > > > > > >>> > > > > > > > > >>> > > > > > > And the > answer > > is: > > >>> > > > > > > > > >>> > > > > > > In > JXPath, > > a decision was > > >>> > made to > > >>> > > > overload the > > >>> > > > > > name attribute > to > > refer to > > >>> > > > > > > an > "element"'s > > property name WRT > > >>> > its > > >>> > > > parent. The > > >>> > > > > > reason this was > done > > was > > >>> > > > > > > to support > query > > maps with > > >>> > non-String keys > > >>> > > > in > > >>> > > > > > JXPath. This > > means that > > >>> > > > > > > anytime > you > > actually want to refer > > >>> > to a > > >>> > > > property whose > > >>> > > > > > name literally > is > > >>> > > > > > > "name", you > must > > treat it as a > > >>> > child element > > >>> > > > rather > > >>> > > > > > than an > > attribute. So > > >>> > > > > > > in your > case you > > could either > > >>> > change "name" > > >>> > > > to "title" > > >>> > > > > > and query > > >>> > > > > > > > [...@title='foo'] > > or simply use > > >>> > [name='foo']. > > >>> > > > > > > > > >>> > > > > > > Regards, > > >>> > > > > > > Matt > > >>> > > > > > > > > >>> > > > > > > --- On > Mon, > > 2/23/09, Matt Benson > > >>> > <gudnabr...@yahoo.com> > > >>> > > > > > wrote: > > >>> > > > > > > > > >>> > > > > > > > From: > Matt > > Benson <gudnabr...@yahoo.com> > > >>> > > > > > > > > Subject: > > Re: JXPath over > > >>> > Generic > > >>> > > > > > > Collection<?>, > > How? > > >>> > > > > > > > To: > > "Commons Users List" > > >>> > <user@commons.apache.org> > > >>> > > > > > > > Date: > > Monday, February 23, > > >>> > 2009, 2:58 > > >>> > > > PM > > >>> > > > > > > > > > >>> > > > > > > > To > follow > > up, the 'name' > > >>> > attribute in > > >>> > > > particular > > >>> > > > > > is what > > >>> > > > > > > > > doesn't > > seem to be working > > >>> > here (change > > >>> > > > it to > > >>> > > > > > e.g. 'game' > > >>> > > > > > > > and > it > > works fine)... if you > > >>> > could file > > >>> > > > a bug it > > >>> > > > > > would help > > >>> > > > > > > > me > remember > > as I don't have > > >>> > time to do > > >>> > > > it myself > > >>> > > > > > right this > > >>> > > > > > > > > minute. > > >>> > > > > > > > > > >>> > > > > > > > -Matt > > >>> > > > > > > > > > >>> > > > > > > > --- On > Mon, > > 2/23/09, Matt > > >>> > Benson <gudnabr...@yahoo.com> > > >>> > > > > > > > > wrote: > > >>> > > > > > > > > > >>> > > > > > > > > > From: > > Matt Benson <gudnabr...@yahoo.com> > > >>> > > > > > > > > > > Subject: Re: JXPath over > > >>> > Generic > > >>> > > > > > > Collection<?>, > > >>> > > > > > > > How? > > >>> > > > > > > > > > To: > > "Commons Users List" > > >>> > <user@commons.apache.org> > > >>> > > > > > > > > > Date: > > Monday, February > > >>> > 23, 2009, > > >>> > > > 12:27 PM > > >>> > > > > > > > > > > >>> > > > > > > > > > > Andrew, > > >>> > > > > > > > > > > I've > > >>> > been meaning > > >>> > > > to look > > >>> > > > > > into this but > > haven't > > >>> > > > > > > > > > > yet. If you have > > >>> > any > > >>> > > > ready-to-run code > > >>> > > > > > you can send > > >>> > > > > > > > to > > >>> > > > > > > > > > the > > list, that wouldn't > > >>> > hurt... > > >>> > > > > > > > > > > >>> > > > > > > > > > -Matt > > >>> > > > > > > > > > > >>> > > > > > > > > > --- On > > Mon, 2/23/09, > > >>> > Andrew Hughes > > >>> > > > <ahhug...@gmail.com> > > >>> > > > > > > > > > > wrote: > > >>> > > > > > > > > > > >>> > > > > > > > > > > > > From: Andrew Hughes > > >>> > <ahhug...@gmail.com> > > >>> > > > > > > > > > > > > Subject: Re: JXPath > > >>> > over > > >>> > > > Generic > > >>> > > > > > > > > > Collection<?>, > > >>> > > > > > > > > > How? > > >>> > > > > > > > > > > > > To: "Commons Users > > >>> > List" > > >>> > > > <user@commons.apache.org> > > >>> > > > > > > > > > > > > Date: Monday, > > >>> > February 23, > > >>> > > > 2009, 5:42 > > >>> > > > > > AM > > >>> > > > > > > > > > > > > OK, email #19 to > > >>> > the list. > > >>> > > > I'm both > > >>> > > > > > > > > > > > > incredibly patient > > >>> > and > > >>> > > > skeptical that > > >>> > > > > > > > > > > > > this will ever > > >>> > work. I might > > >>> > > > try and > > >>> > > > > > run this in > > >>> > > > > > > > a > > >>> > > > > > > > > > > debugger > > >>> > > > > > > > > > > > > and track down > > >>> > > > > > > > > > > > > "how" JXPath > > >>> > traverses the > > >>> > > > DynaBean.... > > >>> > > > > > but given > > >>> > > > > > > > the > > >>> > > > > > > > > > > > > reflection > > >>> > involved > > >>> > > > > > > > > > > > > that might be a > > >>> > painful > > >>> > > > task. > > >>> > > > > > > > > > > > > --AH > > >>> > > > > > > > > > > > > >>> > > > > > > > > > > > > >>> > > > > > > > > > > > > On Tue, Feb 17, > > >>> > 2009 at 1:11 > > >>> > > > PM, Andrew > > >>> > > > > > Hughes > > >>> > > > > > > > <ahhug...@gmail.com> > > >>> > > > > > > > > > > > > wrote: > > >>> > > > > > > > > > > > > >>> > > > > > > > > > > > > > Ping... if > > >>> > anyone can > > >>> > > > help with > > >>> > > > > > this JXPath > > >>> > > > > > > > > > & > > >>> > > > > > > > > > > > > DynaBeans problem > > >>> > I'd be > > >>> > > > > > > > > > > > > > REALLY > > >>> > THANKFUL :) > > >>> > > > > > > > > > > > > > > > >>> > > > > > > > > > > > > > > > >>> > > > > > > > > > > > > > On Fri, Feb > > >>> > 13, 2009 at > > >>> > > > 1:55 PM, > > >>> > > > > > Andrew > > >>> > > > > > > > > Hughes > > >>> > > > > > > > > > <ahhug...@gmail.com> > > >>> > > > > > > > > > > > > wrote: > > >>> > > > > > > > > > > > > > > > >>> > > > > > > > > > > > > >> Howdy, > > >>> > > > > > > > > > > > > >> I've taken > > >>> > Matt's > > >>> > > > suggestion > > >>> > > > > > onboard and > > >>> > > > > > > > I > > >>> > > > > > > > > > have > > >>> > > > > > > > > > > > > investigated > > >>> > DynaBeans. > > >>> > > > > > > > > > > > > >> These look > > >>> > pretty > > >>> > > > good for > > >>> > > > > > all > > >>> > > > > > > > > intestive > > >>> > > > > > > > > > > purposes > > >>> > > > > > > > > > > > > and there's a code > > >>> > > > > > > > > > > > > >> examples > > >>> > below how > > >>> > > > to build > > >>> > > > > > the data > > >>> > > > > > > > > > > structure: > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > > >> + root > > >>> > > > [...@name="ROOT"] > > >>> > > > > > > > > > > > > >> > > >>> > > > + > > >>> > > > > > animal > > [...@name="ANIMAL"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > + dog > > >>> > > > > > > > > > > > > [...@name="DOG"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > + > > >>> > boxer > > >>> > > > [...@name="BOXER"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > + > > >>> > labrador > > >>> > > > > > > [...@name="LABRADOR"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > + cat > > >>> > > > > > > > > > > > > [...@name="CAT"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > + > > >>> > tiger > > >>> > > > > > > [...@name="TIGER-ONE"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > + > > >>> > tiger > > >>> > > > > > > [...@name="TIGER-TWO"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > + > > >>> > tiger > > >>> > > > > > > > [...@name="TIGER-THREE"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > + > > >>> > lion > > >>> > > > [...@name="LION"] > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > > >> And the > > >>> > code looks > > >>> > > > like... > > >>> > > > > > > > > > > > > >> > > >>> > > > > > > > > > > > > >> > > >>> > LazyDynaBean > > >>> > > > > > lazyDynaBean = > new > > >>> > > > > > > > > > > > > LazyDynaBean(); > > >>> > //the > > >>> > > > transpar > > >>> > > >> ... > > >> > > >> [Message clipped] > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscr...@commons.apache.org > For additional commands, e-mail: user-h...@commons.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: user-unsubscr...@commons.apache.org For additional commands, e-mail: user-h...@commons.apache.org