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] > > >