2009-05-22 7 views
2

Ich habe eine einfache Klasse (zu Testzwecken), die ich versuche, die Verwendung von JXPath abzufragen.Verwenden von JXPath zum Abfragen einer Liste

ich eine Liste von verschiedenen Tieren Objekten, und ich möchte für einen Iterator bekommen:

  1. alle Tiere in dem type = 'CAT'

  2. Alle Tiere, wo numLegs = 4

  3. Hier

ist die einfache Klasse:

public class Animal { 

    private UUID uuid; 
    private int numLegs; 
    private AnimalType type; 

    public enum AnimalType { 
     CHICKEN, FROG, DOG, CAT 
    } 

    public Animal(AnimalType type) { 
     this.type = type; 
     uuid = UUID.randomUUID(); 
     switch (type) { 
     case CHICKEN: 
      numLegs = 2; 
      break; 
     case FROG: 
      numLegs = 2; 
      break; 
     case DOG: 
      numLegs = 4; 
      break; 
     case CAT: 
      numLegs = 4; 
      break; 
     } 
    } 

    public UUID getUuid() { 
     return uuid; 
    } 

    public int getNumLegs() { 
     return numLegs; 
    } 

    public AnimalType getType() { 
     return type; 
    } 

    public String toString(){ 
     return "UUID: "+uuid+", Animal: "+type+ ", Legs: "+numLegs; 
    } 

} 

Hier ist die Methode, die ich eine Liste der Tiere zu bauen bin mit mir gegen Abfrage:

private static List<Animal> getAnimals(int numAnimals) { 
    ArrayList<Animal> animals = new ArrayList<Animal>(); 
    for(int i = 0; i<numAnimals; i++){ 
     if(i%4==0){ 
      animals.add(new Animal(AnimalType.CAT)); 
     } 
     else if(i%3==0){ 
      animals.add(new Animal(AnimalType.DOG)); 
     } 
     else if(i%2==0){ 
      animals.add(new Animal(AnimalType.FROG)); 
     } 
     else{ 
      animals.add(new Animal(AnimalType.CHICKEN)); 
     } 

    } 

    return animals; 
} 

Hier ist, wie ich die Abfrage auszuführen versuchen:

public static void main(String[] args){ 
    List<Animal> animals = getAnimals(10000); 

    JXPathContext animsContext = JXPathContext.newContext(animals); 

    Iterator<BeanPointer> iter = 
     animsContext.iteratePointers("/*[type='CAT']"); 

    List<Animal> cats = new ArrayList<Animal>(); 


    while(iter.hasNext()){ 
     cats.add((Animal) iter.next().getParent().getValue()); 
    } 
    System.out.println("Number of Cats is: "+cats.size()); 
} 

Dieser Teil:

Iterator<BeanPointer> iter = 
     animsContext.iteratePointers("/*[type='CAT']"); 

funktioniert nicht. Was mache ich falsch? Ich kann es auch nicht für/* [numLegs = 4] verwenden.

Antwort

5

Ich habe noch nie JXPath verwendet, aber ich würde erwarten, dass es einen Wurzelknoten sein, in welchem ​​Fall

/*[type='CAT'] 

würde bedeuten, „gib mir den Stammknoten, nur wenn es ein Attribut hat geben Sie gleich CAT „

ich denke, was Sie nach ist etwas mehr wie

/*/*[type='CAT'] 

, die lesen würde wie“ mir geben Knoten direkt undern eath den Wurzelknoten, der einen Attributtyp aufweisen, die CAT gleich“

Brian Vorschlag

//*[type='CAT'] 

wie liest:‚Gib mir alle Knoten irgendwo im Baum, der einen Attributtyp haben, der gleich CAT‘

Hoffe, dass hilft ein bisschen.

2

Ich bin mir nicht sicher, was oben nicht funktioniert. Allerdings ein paar Punkte.

  1. Ich bin nicht sicher, dass Aufzählungen funktionieren, wie Sie erwarten. Ihre JXPath-Abfrage fragt nach einem Typ, bei dem getType() eine Aufzählung und keine Zeichenfolge zurückgibt. Ich bin mir nicht sicher, ob JXPath so clever ist. Aufzählungen.
  2. [type='CAT'] an sich ist kein XPath-Ausdruck. Ich würde erwarten, so etwas wie //*[type='CAT']

Also ich würde versuchen Sie folgendes:

  1. eine getTypeName() Methode implementieren, die die Aufzählungsnamen zurückgibt z.B. CAT/DOG usw. und Abfrage mit diesem
  2. Versuchen Sie einen XPath von (ohne Prädikate), um zu bestätigen, dass JXpath eine ArrayList wie erwartet abfragt.
Verwandte Themen