Προγραμματισμός

Ερωτήματα αντικειμένου Java χρησιμοποιώντας το JXPath

Σε ένα πρόσφατο έργο, χρειαζόμουν έναν εύκολο τρόπο να διασχίσω δέντρα αντικειμένων Java και να εξαγάγω τιμές από τα αντικείμενα. Αντί να συνεχίζω συνεχώς τεράστιες ρυθμίσεις επαναλήψεων-αν-αλλιώς, ήθελα ένα εργαλείο που θα μου επέτρεπε να πω απλώς, "Θέλω το αντικείμενο με id = X, και από αυτό το αντικείμενο, χρειάζομαι την αξία της ιδιότητας Α." Στην ουσία, χρειαζόμουν ένα εργαλείο αναζήτησης αντικειμένων.

Το JXPath είναι ένα τέτοιο εργαλείο αντικειμένου. Πρόκειται για ένα στοιχείο Apache Commons που σας δίνει τη δυνατότητα να ζητάτε σύνθετα δέντρα αντικειμένων χρησιμοποιώντας τη γνωστή γλώσσα έκφρασης XPath. Χρησιμοποίησα το JXPath ευρέως στο έργο μου και επιτάχυνε σημαντικά τα πράγματα, κάνοντας τους αλγόριθμους εξαγωγής αξίας ένα αεράκι.

Ωστόσο, το JXPath δεν είναι ευρέως τεκμηριωμένο. Επειδή όμως εξερεύνησα το στοιχείο σε βάθος, αποφάσισα να γράψω τα ευρήματά μου σε ένα εκτεταμένο σεμινάριο JXPath, το οποίο μπορείτε να βρείτε στον ιστότοπό μου. Αυτό το άρθρο είναι μια σύντομη έκδοση αυτού του σεμιναρίου για να ξεκινήσετε γρήγορα με το JXPath.

Σημείωση: Μπορείτε να πραγματοποιήσετε λήψη του συνοδευτικού δείγματος κώδικα από τους πόρους.

Παράδειγμα μοντέλου

Για λόγους απεικόνισης, θα χρησιμοποιήσουμε ένα απλό μοντέλο: α Εταιρία με διάφορα τμήματα, το καθένα με διάφορα υπαλλήλους. Εδώ είναι το μοντέλο της τάξης:

Φυσικά, χρειαζόμαστε μερικά δείγματα δεδομένων για το μοντέλο:

Εταιρία

Τμήμα

Υπάλληλος (όνομα, τίτλος εργασίας, ηλικία)

Acme Inc.

Εκπτώσεις

Johnny, εκπρόσωπος πωλήσεων, 45

Sarah, εκπρόσωπος πωλήσεων, 33

Magda, βοηθός γραφείου, 27

Λογιστική

Steve, Επικεφαλής ελεγκτής, 51

Peter, Βοηθός ελεγκτή, 31

Susan, βοηθός γραφείου, 27

Με αυτό στη θέση του, ας αρχίσουμε να χρησιμοποιούμε το JXPath!

Εκτέλεση απλών ερωτημάτων JXPath

Το απλούστερο δυνατό ερώτημα εξάγει ένα αντικείμενο από το δέντρο αντικειμένων. Για παράδειγμα, για ανάκτηση Εταιρία, χρησιμοποιήστε τον ακόλουθο κωδικό:

JXPathContext περιβάλλον = JXPathContext.newContext (εταιρεία); Εταιρεία c = (Εταιρεία) context.getValue (".");

Η πρώτη γραμμή δείχνει τη δημιουργία ενός συμφραζόμενα, το σημείο εκκίνησης για όλες τις εκφράσεις XPath του JXPath στο δέντρο αντικειμένων (συγκρίσιμο με το rootnode στοιχείο σε ένα έγγραφο XML). Η δεύτερη γραμμή κώδικα εκτελεί το πραγματικό ερώτημα. Από το δικό μας συμφραζόμενα ξεκινά σε επίπεδο εταιρείας, για να ανακτήσει το Εταιρία αντικείμενο, απλά χρησιμοποιούμε τον επιλογέα τρέχοντος στοιχείου '.'.

Χρήση κατηγοριών και μεταβλητών

Ενα Υπάλληλος είναι ένα παιδικό αντικείμενο ενός Τμήμα. Για να ανακτήσετε το Υπάλληλος με όνομα "Johnny" χρησιμοποιήστε τον ακόλουθο κωδικό (Εταιρία εξακολουθεί να είναι συμφραζόμενααφετηρία):

Employee emp = (Υπάλληλος) context.getValue ("/ departmentList / υπάλληλοι [name = 'Johnny']");

Βασικά, ο κωδικός έχει ως εξής: "Αναζήτηση όλων Τμήμαs από την αρχή για το Υπάλληλος αντικείμενο του οποίου το όνομα το χαρακτηριστικό έχει την τιμή 'Γιαννάκης'."

Το παραπάνω απόσπασμα κώδικα απεικονίζει τον τρόπο χρήσης ενός κατηγορήματος για την αναζήτηση αντικειμένων χρησιμοποιώντας συγκεκριμένες τιμές. Η χρήση κατηγοριών είναι συγκρίσιμη με τη χρήση του όρου WHERE στο SQL. Μπορούμε ακόμη και να συνδυάσουμε πολλά προγνωστικά σε ένα ερώτημα:

Employee emp = (Υπάλληλος) context.getValue ("/ departmentList / υπάλληλοι [όνομα = 'Susan' και ηλικία = 27]");

Εκτός αν χρησιμοποιείτε ένα ad-hoc, εφάπαξ ερώτημα, η εφαρμογή κωδικοποιημένων ερωτημάτων συνήθως δεν είναι εφικτή. Είναι καλύτερο να ορίσετε ένα επαναχρησιμοποιήσιμο ερώτημα που μπορείτε να εκτελέσετε με διαφορετικές παραμέτρους. Για να ικανοποιήσει την παραμετροποίηση ερωτημάτων, υποστηρίζει το JXPath μεταβλητές σε ερωτήματα. Χρησιμοποιώντας μεταβλητές, ο παραπάνω κώδικας μοιάζει τώρα με αυτό:

context.getVariables (). δηλώστεVariable ("όνομα", "Susan"); context.getVariables (). δηλώστεVariable ("ηλικία", νέος ακέραιος (27)) Employee emp = (Employee) context.getValue ("/ departmentList / εργαζόμενοι [όνομα =$ όνομα και ηλικία =ηλικία $]");

Επανάληψη συλλογών

Το JXPath μπορεί να παρέχει επανάληψη σε όλα τα αντικείμενα που ανακτώνται από ένα ερώτημα, σαν να επαναλαμβάνει ένα σύνολο αποτελεσμάτων. Το παρακάτω απόσπασμα δείχνει πώς μπορείτε να επαναλάβετε σε όλους Τμήμαμικρό:

για (Iterator iter = konteks.iterate ("/ departmentList"); iter.hasNext ();) {Τμήμα d = (Τμήμα) iter.next (); // ...}

Για ανάκτηση όλων Υπάλληλοςαπό όλα Τμήμακαι επαναλάβετε:

για (Iterator iter = konteks.iterate ("/ departmentList / υπάλληλοι"); iter.hasNext ();) {Employee emp = (Υπάλληλος) iter.next (); // ...}

Για ανάκτηση όλων Υπάλληλοςάνω των 30 ετών από το τμήμα πωλήσεων:

για (Iterator iter = konteks.iterate ("/ departmentList [name = 'Sales'] / εργαζόμενοι [ηλικία> 30]"); iter.hasNext ();) {Employee emp = (Υπάλληλος) iter.next (); // ...}

Και το παραπάνω παράδειγμα με μεταβλητές:

context.getVariables (). δηλώστεVariable ("deptName", "Εκπτώσεις"); context.getVariables (). δηλώστεVariable ("minAge", νέος ακέραιος (30)); για (Iterator iter = context.iterate ("/ departmentList [name =$ deptName] / υπάλληλοι [ηλικία>$ minAge] "); iter.hasNext ();) {Employee emp = (Employee) iter.next (); // ...}

Αυτά τα δύο τελευταία αποσπάσματα κώδικα δείχνουν επίσης τη χρήση πολλών κατηγοριών σε ένα ερώτημα XPath.

Δείκτες

ΕΝΑ Δείκτης είναι ένα αντικείμενο βοηθητικού προγράμματος JXPath που αντιπροσωπεύει μια αναφορά στη θέση ενός αντικειμένου στο δέντρο αντικειμένων. Για παράδειγμα, α Δείκτης μπορεί να αναφέρεται στον «πρώτο υπάλληλο του δεύτερου τμήματος». Σε σύγκριση με αντικείμενα που ανακτήθηκαν απευθείας από το δέντρο, Δείκτηςπροσφέρουν πρόσθετες λειτουργίες όπως η εκτέλεση του σχετικά ερωτήματα διά μέσου σχετικά πλαίσια (περισσότερα για αυτό αργότερα).

Χρησιμοποιώντας δείκτες

Εχοντας ένα Δείκτης Αναφορά σε ένα αντικείμενο στο δέντρο αντικειμένων είναι σχεδόν πανομοιότυπο με την ανάκτηση αντικειμένων απευθείας:

JXPathContext konteks = JXPathContext.newContext (εταιρεία); Δείκτης empPtr = πλαίσιο.getPointer("/ departmentList [name = 'Sales'] / εργαζόμενοι [ηλικία> 40]"); System.out.println (empPtr); //παραγωγή: / departmentList [1] / υπάλληλοι [1] System.out.println (((Υπάλληλος) empPtr.getValue ()) .getName ()); //παραγωγή: γιαννάκης

Σημειώστε ότι το ΔείκτηςΗ έξοδος δείχνει ότι a Δείκτης περιγράφει τη θέση ενός αντικειμένου και όχι το ίδιο το αντικείμενο. Σημειώστε επίσης ότι το πραγματικό αντικείμενο το Δείκτης αναφέρεται μπορεί να ανακτηθεί μέσω του Δείκτης'μικρό getValue () μέθοδος.

Οι δείκτες μπορούν επίσης να επαναληφθούν, όπως δείχνει το ακόλουθο απόσπασμα:

για (Iterator iter = περιβάλλον.iteratePointers("/ departmentList [name = 'Sales'] / εργαζόμενοι [ηλικία> 30]"); iter.hasNext ();) {Pointer empPtr = (Δείκτης) iter.next (); // ...}

Σχετικό πλαίσιο και σχετικά ερωτήματα

Από το α Δείκτης περιγράφει μια τοποθεσία, μπορεί να χρησιμοποιηθεί ως σημείο αναφοράς για πλοήγηση σε ολόκληρο το δέντρο αντικειμένων. Για να το κάνετε αυτό, χρησιμοποιήστε το Δείκτης ως το ριζικό αντικείμενο (Θυμηθείτε να χρησιμοποιείτε το Εταιρία αντικείμενο για αυτό νωρίτερα;) σε ένα λεγόμενο σχετικό πλαίσιο. Από αυτό το σχετικό περιβάλλον, μπορείτε να υποβάλετε ερώτημα σε ολόκληρο το δέντρο αντικειμένων εκτελώντας σχετικά ερωτήματα. Αυτή η προηγμένη χρήση του ΔείκτηςΤο s προσφέρει μεγάλη ευελιξία, όπως δείχνουν τα παρακάτω παραδείγματα.

Για να ξεκινήσετε, δείτε πώς δημιουργείτε ένα σχετικό πλαίσιο:

για (Iterator iter = context.iteratePointers ("/ departmentList [name = 'Sales'] / υπαλλήλους [ηλικία> 30]"); iter.hasNext ();) {Pointer empPtr = (Pointer) iter.next (); JXPathContext relatifContext = konteks.getRelativeContext (empPtr); }

Σε αυτό το απόσπασμα κώδικα, δημιουργείται ένα νέο σχετικό περιβάλλον για διαδοχικό υπάλληλος δείκτες.

Χρησιμοποιώντας το σχετικό περιβάλλον, τα ερωτήματα XPath μπορούν να εκτελεστούν σε ολόκληρο το δέντρο αντικειμένων των αδελφών, των παιδιών και των αντικειμένων γονέα / παππούδων, όπως δείχνει το ακόλουθο απόσπασμα:

// Τρέχων εργαζόμενος Employee emp = (Employee) relatifContext.getValue ("."); // Όνομα υπαλλήλου String name = (String) relatifContext.getValue ("./ name"); // Όνομα του τμήματος στο οποίο ανήκει ο υπάλληλος (ένα γονικό αντικείμενο) String deptName = (String) relatifContext.getValue ("../ name"); // Όνομα της εταιρείας στην οποία ανήκει ο υπάλληλος (αντικείμενο "παππού") String compName = (String) relatifContext.getValue ("../../ name"); // Όλοι οι συνεργάτες αυτού του υπαλλήλου (αδέρφια αντικείμενα) για το (Iterator empIter = relatifContext.iterate ("../ karyawan"); empIter.hasNext ();) {Συνεργάτης υπαλλήλου = (Υπάλληλος) empIter.next () // ...}

Περίληψη

Το JXPath είναι ένα εξαιρετικά χρήσιμο εργαλείο για την περιήγηση, την πλοήγηση και την αναζήτηση σύνθετων δέντρων αντικειμένων. Επειδή χρησιμοποιεί τη γλώσσα έκφρασης XPath για τα ερωτήματά του, ένα μεγάλο σώμα υλικού αναφοράς είναι διαθέσιμο για να σας βοηθήσει να δημιουργήσετε αποτελεσματικά αλλά πολύπλοκα ερωτήματα ανάκτησης αντικειμένων. Προστίθεται ακόμη περισσότερη ευελιξία χρησιμοποιώντας Δείκτηςs και σχετικές συνθήκες.

Αυτό το σύντομο άρθρο χαράζει μόνο την επιφάνεια των δυνατοτήτων του JXPath, για μια πιο εμπεριστατωμένη συζήτηση με πιο προηγμένα παραδείγματα χρήσης, διαβάστε ολόκληρο το σεμινάριό μου.

Ο Bart van Riel ασχολείται με τον Java και τον αντικειμενοστραφή κόσμο για περισσότερα από επτά χρόνια. Έχει εργαστεί τόσο ως προγραμματιστής όσο και ως εκπαιδευτής σε αντικειμενοστραφή και Java πεδία. Σήμερα απασχολείται από την παγκόσμια εταιρεία συμβούλων πληροφορικής Capgemini ως αρχιτέκτονας λογισμικού και πρωταγωνιστής ανοιχτού κώδικα.

Μάθετε περισσότερα σχετικά με αυτό το θέμα

  • Κατεβάστε τον πηγαίο κώδικα για αυτό το άρθρο
  • Δείτε το πλήρες σεμινάριο JXPath
  • Apache Commons JXPath
  • Ένα καλό σεμινάριο XPath
  • Περιηγηθείτε στα άρθρα στο JavaWorld'μικρό Εργαλεία ανάπτυξης Κέντρο Ερευνών
  • Συνεχίστε με τα νέα JavaWorld! Εγγραφείτε δωρεάν Επιχείρηση Java ενημερωτικό δελτίο

Αυτή η ιστορία, "Ερωτήματα αντικειμένου Java που χρησιμοποιούν το JXPath" δημοσιεύτηκε αρχικά από την JavaWorld.