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 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 @name property of each bean, user UPPER to make them distinct for examples. root.set("name","ROOT"); animal.set("name","ANIMAL"); dog.set("name","DOG"); cat.set("name","CAT"); boxer.set("name","BOXER"); labrador.set("name","LABRADOR"); tiger1.set("name","TIGER-ONE"); tiger2.set("name","TIGER-TWO"); tiger3.set("name","TIGER-THREE"); lion.set("name","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",1,tiger3);//duplicate cat.set("lion",0,lion); JXPathContext context = JXPathContext.newContext(lazyDynaBean); String query = "/root/animal/cat/tiger"; Object value = context.getValue(query); But there's a problem with JXPath querying this also. Absolute Paths like '/root/animal/cat/tiger' or '/root/animal/cat/tiger'[2]' work perfectly. But I don't have anyluck doing "deep" searches. For examples the following just won't work. '//cat' //*...@name='LION'] /root/animal/cat/tig...@name='TIGER-TWO'] Things are looking up, but is this behavior to be expected? Cheers, --AH On Thu, Feb 12, 2009 at 6:43 AM, Matt Benson <gudnabr...@yahoo.com> wrote: > > > > > --- On Wed, 2/11/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 11, 2009, 4:19 AM > > Still No Luck, I have removed recursive generic collections > > and have tried > > the following code... this is becoming a marathon effort > > :'( > > > > public class Thing { > > > > public Thing(String name) { > > this.name = name; > > } > > private String name = ""; > > > > public String getName() { > > return name; > > } > > private ArrayList<Thing> children = new > > ArrayList<Thing>(); > > > > public ArrayList<Thing> getChildren() { > > return children; > > } > > > > } > > > > > > public static void main(String[] args) { > > //get some same data > > Thing animal = new Thing("Animal"); > > //Animal.Dog.* > > Thing dog = new Thing("Dog"); > > dog.getChildren().add(new > > Thing("Labrador")); > > dog.getChildren().add(new > > Thing("Boxer")); > > animal.getChildren().add(dog); > > //Animal.Cat.* > > Thing cat = new Thing("Cat"); > > cat.getChildren().add(new Thing("Lion")); > > cat.getChildren().add(new > > Thing("Tiger")); > > animal.getChildren().add(cat); > > > > //run a query on it > > JXPathContext context = > > JXPathContext.newContext(animal); > > String query = "/Animal"; > > Thing result = (Thing) context.getValue(query); > > String path = context.getPointer(query).asPath(); > > System.out.println("Ran '" + query + > > "' and got '" + > > result.getName() + "' on path '" + path + > > "'."); > > } > > > > What would you be trying to select? If you want to know how to look for a > given Thing in this graph, I can probably help. If you want to know what > graph will allow you to use a preconceived notion of the xpath you want to > use, that will be harder. You might use [beanutils] dynabeans in > conjunction with [jxpath] to try and achieve the latter. > > -Matt > > > > > > > > > On Wed, Feb 11, 2009 at 3:08 PM, Andrew Hughes > > <ahhug...@gmail.com> wrote: > > > > > Yeah, that makes sense. The part that was confusing me > > is that if I > > > have... > > > > > > public class Thing { > > > > > > private List<Thing> children; > > > > > > } > > > > > > I was assuming I would need to prefix all of my > > expressions "steps" with > > > '/children'. From what you said earlier this > > is not the case as collections > > > are "auto traversed/loaded". > > > > > > Thanks again matt! I won't get to test this out > > til later tonight be look > > > foward to seeing it working!!! > > > > > > Andrew > > > > > > > > > On Wed, Feb 11, 2009 at 2:57 PM, Matt Benson > > <gudnabr...@yahoo.com> wrote: > > > > > >> > > >> It should be as simple as Thing _containing_ a > > List<Thing> rather than > > >> _being_ a List<Thing>. Composition over > > inheritance, do you see? > > >> > > >> HTH, > > >> Matt > > >> > > >> > > >> --- On Tue, 2/10/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>, > > >> gudnabr...@yahoo.com > > >> > Date: Tuesday, February 10, 2009, 7:06 PM > > >> > Matt, Thank You. > > >> > > > >> > Is there any other data structure I can use > > that would work > > >> > with JXPath? My > > >> > requirement is that... a "Thing" > > can have contain > > >> > multiple child "Thing(s)" > > >> > (and the children are allowed to be > > non-unique). > > >> > This is equivalent to an XML element as it > > can contain > > >> > multiple child > > >> > elements, how do these guy's handle it I > > wonder? > > >> > > > >> > --Andrew > > >> > > > >> > > > >> > On Wed, Feb 11, 2009 at 9:09 AM, Matt Benson > > >> > <gudnabr...@yahoo.com> wrote: > > >> > > > >> > > > > >> > > I admit I hadn't looked at this with > > a highly > > >> > critical eye, but this > > >> > > business of Thing extending > > ArrayList<Thing> > > >> > seems quite strange to me. > > >> > > JXPath basically functions by > > "opening up" > > >> > collections automatically, so > > >> > > the very fact that Thing is itself a > > Collection > > >> > implies that a Thing will be > > >> > > opened up, and its children will be > > searched... but in > > >> > this example, either > > >> > > there are no children, at the leaves, or > > the children > > >> > themselves are > > >> > > (possibly empty) collections. It looks > > as though > > >> > you're trying to represent > > >> > > a tree structure. This may be a good > > example of a > > >> > reason for the idea of > > >> > > composition over inheritance. I > > don't think > > >> > you're going to get any > > >> > > traction using JXPath with this object > > model. > > >> > > > > >> > > Sorry for the bad news, > > >> > > Matt > > >> > > > > >> > > > > >> > > --- On Tue, 2/10/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, February 10, 2009, > > 7:16 AM > > >> > > > Still busted. Example is now > > simplified. As soon > > >> > as a > > >> > > > generic Collection > > >> > > > becomes involved BOOM! > > >> > > > > > >> > > > The Main Method to exec: > > >> > > > public class App { > > >> > > > public static void main( > > String[] args ){ > > >> > > > JXPathContext context = > > >> > > > JXPathContext.newContext(new > > ThingRoot()); > > >> > > > > > >> > > > > > >> > > > System.out.println(((Thing)context.getValue("/root")).getName()); > > >> > > > } > > >> > > > } > > >> > > > > > >> > > > The (populated) context root I am > > using, where > > >> > root is a > > >> > > > single object > > >> > > > holding a List of Thing's. > > >> > > > package jxpathresearch; > > >> > > > > > >> > > > import java.util.ArrayList; > > >> > > > import java.util.List; > > >> > > > > > >> > > > public class ThingRoot { > > >> > > > private List<Thing> root > > new > > >> > ArrayList(); //this > > >> > > > will serve as the root. > > >> > > > public ThingRoot() { > > >> > > > Thing animal = new > > >> > Thing("Animal"); > > >> > > > root.add(animal);//Animal > > >> > > > Thing dog = new > > Thing("Dog"); > > >> > > > > > animal.add(dog);//Animal.Dog > > >> > > > dog.add(new > > >> > > > > > >> > > > Thing("Labrador"));//Animal.Dog.Labrador > > >> > > > dog.add(new > > >> > > > > > Thing("Boxer"));//Animal.Dog.Boxer > > >> > > > } > > >> > > > public List<Thing> > > getRoot() { return > > >> > root; } > > >> > > > } > > >> > > > > > >> > > > Finally here's a very simple > > 'Thing' > > >> > that > > >> > > > contains a List of Thing(s): > > >> > > > public class Thing extends > > ArrayList<Thing> > > >> > { > > >> > > > public Thing(String > > name){this.name = name;} > > >> > > > private String name = > > ""; > > >> > > > public String getName() {return > > name;} > > >> > > > } > > >> > > > > > >> > > > I can't query anything beyond > > /root, it > > >> > doesn't > > >> > > > seem to ever get traversed. > > >> > > > I would expect results for //Thing > > and > > >> > > > //thi...@name='Labrador'] > > etc but I > > >> > > > get no results only exceptions. > > >> > > > > > >> > > > > > >> > > > My brain is hurting. > > >> > > > > > >> > > > > > >> > > > > > >> > > > On Tue, Feb 10, 2009 at 12:22 AM, > > Andrew Hughes > > >> > > > <ahhug...@gmail.com> wrote: > > >> > > > > > >> > > > > I've noew tested a whole > > heap of > > >> > expressions even > > >> > > > //name='Tiger' nothing > > >> > > > > works. > > >> > > > > > > >> > > > > On Tue, Feb 10, 2009 at 12:01 > > AM, Andrew > > >> > Hughes > > >> > > > <ahhug...@gmail.com>wrote: > > >> > > > > > > >> > > > >> I got cracking on testing > > this out... no > > >> > luck > > >> > > > (yet). Here's my testing > > >> > > > >> code if some kind person > > could please > > >> > take a > > >> > > > look.... > > >> > > > >> First my generic > > collection hierarchy > > >> > (which only > > >> > > > contains a name and > > >> > > > >> children)... > > >> > > > >> > > >> > > > >> package jxpathresearch; > > >> > > > >> > > >> > > > >> import > > java.util.ArrayList; > > >> > > > >> > > >> > > > >> public class HierarchyPojo > > extends > > >> > > > ArrayList<HierarchyPojo> { > > >> > > > >> > > >> > > > >> public > > HierarchyPojo(String name){ > > >> > > > >> > > this.setName(name); > > >> > > > >> } > > >> > > > >> private String name = > > ""; > > >> > > > >> > > >> > > > >> public String > > getName() { > > >> > > > >> return name; > > >> > > > >> } > > >> > > > >> public void > > setName(String name) { > > >> > > > >> this.name = name; > > >> > > > >> } > > >> > > > >> > > >> > > > >> } > > >> > > > >> > > >> > > > >> > > >> > > > >> Next, the wrapper for the > > root context > > >> > (as Matt > > >> > > > suggested) and populated > > >> > > > >> with animals... > > >> > > > >> > > >> > > > >> package jxpathresearch; > > >> > > > >> > > >> > > > >> > > >> > > > >> public class > > CollectionRoot { > > >> > > > >> > > >> > > > >> > > >> > > > >> private HierarchyPojo > > hierarchyPojo; > > >> > > > >> > > >> > > > >> > > >> > > > >> public > > CollectionRoot(){ > > >> > > > >> > > >> > > > >> //Animal > > >> > > > >> > > >> > > > >> hierarchyPojo = > > new > > >> > > > HierarchyPojo("Animal"); > > >> > > > >> > > >> > > > >> //Animal.Dog > > >> > > > >> > > >> > > > >> HierarchyPojo dog > > = new > > >> > > > HierarchyPojo("Dog"); > > >> > > > >> > > >> > > > >> > > //Animal.Dog.Labrador > > >> > > > >> > > >> > > > >> dog.add(new > > >> > > > > > HierarchyPojo("Labrador")); > > >> > > > >> > > >> > > > >> //Animal.Dog.Boxer > > >> > > > >> > > >> > > > >> dog.add(new > > >> > > > HierarchyPojo("Boxer")); > > >> > > > >> > > >> > > > >> > > //Animal.Dog.Mastiff > > >> > > > >> > > >> > > > >> dog.add(new > > >> > > > > > HierarchyPojo("Mastiff")); > > >> > > > >> > > >> > > > >> //Animal.Cat > > >> > > > >> > > >> > > > >> HierarchyPojo cat > > = new > > >> > > > HierarchyPojo("Cat"); > > >> > > > >> > > >> > > > >> //Animal.Cat.Tiger > > >> > > > >> > > >> > > > >> cat.add(new > > >> > > > HierarchyPojo("Tiger")); > > >> > > > >> > > >> > > > >> > > //Animal.Cat.Cougar > > >> > > > >> > > >> > > > >> cat.add(new > > >> > > > HierarchyPojo("Cougar")); > > >> > > > >> > > >> > > > >> > > //Animal.Cat.Leopard > > >> > > > >> > > >> > > > >> cat.add(new > > >> > > > > > HierarchyPojo("Leopard")); > > >> > > > >> > > >> > > > >> //Add Animal.Dog > > & > > >> > Animal.Cat > > >> > > > >> > > >> > > > >> > > hierarchyPojo.add(dog); > > >> > > > >> > > >> > > > >> > > hierarchyPojo.add(cat); > > >> > > > >> > > >> > > > >> } > > >> > > > >> > > >> > > > >> > > >> > > > >> public HierarchyPojo > > >> > getHierarchyPojo() > > >> > > > {return hierarchyPojo;} > > >> > > > >> > > >> > > > >> > > >> > > > >> public void > > >> > setHierarchyPojo(HierarchyPojo > > >> > > > hierarchyPojo) > > >> > > > >> {this.hierarchyPojo = > > hierarchyPojo;} > > >> > > > >> > > >> > > > >> > > >> > > > >> } > > >> > > > >> > > >> > > > >> > > >> > > > >> Finally invoke and test... > > >> > > > >> > > >> > > > >> public class App > > >> > > > >> > > >> > > > >> { > > >> > > > >> > > >> > > > >> public static void > > main( String[] > > >> > args ) > > >> > > > >> > > >> > > > >> { > > >> > > > >> > > >> > > > >> JXPathContext > > context = > > >> > > > JXPathContext.newContext(new > > >> > > > >> CollectionRoot()); > > >> > > > >> > > >> > > > >> String query = > > >> > > > > > >> > > > "//hierarchypo...@name='Tiger']"; > > >> > > > >> > > >> > > > >> String fName = > > >> > > > context.getValue(query).toString(); > > >> > > > >> > > >> > > > >> > > System.out.println("Ran > > >> > > > '"+query+"' and > > got > > >> > > > > > '"+fName+"'"); > > >> > > > >> > > >> > > > >> } > > >> > > > >> > > >> > > > >> } > > >> > > > >> > > >> > > > >> > > >> > > > >> > > >> > > > >> Above, should find one > > entry for > > >> > > > 'name=Tiger' but it does > > not, I get an > > >> > > > >> exception. This still > > doesn't seem > > >> > to traverse > > >> > > > the Collection correctly. Any > > >> > > > >> help would be most > > welcome. > > >> > > > >> Exception in thread > > "main" > > >> > > > >> > > >> > > > org.apache.commons.jxpath.JXPathNotFoundException: > > >> > > > No value for xpath: > > >> > > > >> > > //hierarchypo...@name='Tiger'] > > >> > > > >> > > >> > > > >> Thanks for reading, > > >> > > > >> Andrew > > >> > > > >> > > >> > > > >> > > >> > > > >> > > >> > > > >> On Mon, Feb 9, 2009 at > > 10:24 PM, Andrew > > >> > Hughes > > >> > > > <ahhug...@gmail.com>wrote: > > >> > > > >> > > >> > > > >>> Thanks Matt - I will > > test this out > > >> > tomorrow > > >> > > > when I am back in the > > >> > > > >>> office... > > >> > > > >>> > > >> > > > >>> Being constructive... > > >> > > > >>> Surely this should at > > least be a > > >> > precondition > > >> > > > check and throw a specific > > >> > > > >>> exception if it's > > not supported? > > >> > > > >>> Thank You > > >> > > > >>> --Andrew > > >> > > > >>> > > >> > > > >>> > > >> > > > >>> On Mon, Feb 9, 2009 at > > 2:27 PM, Matt > > >> > Benson > > >> > > > <gudnabr...@yahoo.com>wrote: > > >> > > > >>> > > >> > > > >>>> > > >> > > > >>>> Most likely your > > problem is not > > >> > with > > >> > > > generics, but simply with the fact > > >> > > > >>>> that JXPath has a > > hard time > > >> > using a > > >> > > > collection as its root. The > > easiest > > >> > > > >>>> workaround is to > > use some parent > > >> > object to > > >> > > > hold a reference to your > > >> > > > >>>> container. > > >> > > > >>>> > > >> > > > >>>> HTH, > > >> > > > >>>> Matt > > >> > > > >>>> > > >> > > > >>>> > > >> > > > >>>> --- On Sun, > > 2/8/09, Andrew > > >> > Hughes > > >> > > > <ahhug...@gmail.com> wrote: > > >> > > > >>>> > > >> > > > >>>> > From: Andrew > > Hughes > > >> > > > <ahhug...@gmail.com> > > >> > > > >>>> > Subject: > > JXPath over > > >> > Generic > > >> > > > Collection<?>, How? > > >> > > > >>>> > To: > > "Commons Users > > >> > List" > > >> > > > <user@commons.apache.org> > > >> > > > >>>> > Date: Sunday, > > February 8, > > >> > 2009, 5:09 > > >> > > > PM > > >> > > > >>>> > Hi All, > > >> > > > >>>> > Hopefully the > > solution is > > >> > as easy as > > >> > > > the question. I would > > >> > > > >>>> > like to > > perform > > >> > > > >>>> > evaluation on > > a (very > > >> > simple) generic > > >> > > > collection... as you > > >> > > > >>>> > can see below > > >> > > > >>>> > > > (HeirarchyPojo). I should > > >> > be able to > > >> > > > ask for a > > >> > > > >>>> > > > HeirarchyPojo's with > > >> > > > >>>> > > > name='Bill' or the > > >> > 3rd > > >> > > > Child... The problem is that > > >> > > > >>>> > nothing ever > > evaluate on > > >> > > > >>>> > this data > > structure. > > >> > What's the > > >> > > > deal with Generic > > >> > > > >>>> > Collections > > and JXPath? > > >> > > > >>>> > > > >> > > > >>>> > p.s this is > > not in the > > >> > userguide and > > >> > > > would be a most > > >> > > > >>>> > welcomed > > addition (if > > >> > > > >>>> > we can nut > > this out with > > >> > your help). > > >> > > > >>>> > > > >> > > > >>>> > Cheers. > > >> > > > >>>> > > > >> > > > >>>> > > > >> > > > >>>> > package > > xpath.and.generics; > > >> > > > >>>> > > > >> > > > >>>> > import > > java.util.ArrayList; > > >> > > > >>>> > > > >> > > > >>>> > public class > > HeirarchyPojo > > >> > extends > > >> > > > >>>> > > > >> > ArrayList<HeirarchyPojo>{ > > >> > > > >>>> > > > >> > > > >>>> > public > > >> > HeirarchyPojo(){} > > >> > > > >>>> > > > >> > > > >>>> > private > > String id; > > >> > > > >>>> > private > > String name; > > >> > > > >>>> > > > >> > > > >>>> > public > > String getId() { > > >> > > > >>>> > > > return id; > > >> > > > >>>> > } > > >> > > > >>>> > > > >> > > > >>>> > public > > void > > >> > setId(String id) { > > >> > > > >>>> > > > this.id = id; > > >> > > > >>>> > } > > >> > > > >>>> > > > >> > > > >>>> > public > > String getName() > > >> > { > > >> > > > >>>> > > > return name; > > >> > > > >>>> > } > > >> > > > >>>> > > > >> > > > >>>> > public > > void > > >> > setName(String name) > > >> > > > { > > >> > > > >>>> > > > this.name = name; > > >> > > > >>>> > } > > >> > > > >>>> > > > >> > > > >>>> > } > > >> > > > >>>> > > >> > > > >>>> > > >> > > > >>>> > > >> > > > >>>> > > >> > > > >>>> > > >> > > > > > >> > > > --------------------------------------------------------------------- > > >> > > > >>>> 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 > > >> > > > > >> > > > > >> > > >> > > >> > > >> > > >> > > --------------------------------------------------------------------- > > >> 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 > >