SelectPath.jws Sample

This topic inludes the source code for the SelectPath.jws Sample.

Sample Location

This sample is located in the following directory in your WebLogic Workshop installation:

BEA_HOME/weblogic81/samples/workshop/SamplesApp/WebServices/xmlBeans/xquery/

Sample Source Code


001 package xmlBeans.xquery; 
002 
003 import com.bea.xml.XmlCursor;
004 import com.bea.xml.XmlObject;
005 
006 /**
007  * A web service demonstrating how to use the selectPath
008  * method to execute an XQuery expressions. Compare the code in this
009  * web service with the code in the SimpleExpressions service. That
010  * service uses the XmlCursor.execQuery method to execute expressions.
011  <br/><br/>
012  
013  * You can call the selectPath method from either an XmlObject or XmlCursor
014  * instance. Calling from XmlObject returns an XmlObject array. Calling
015  * from XmlCursor returns void, and you use methods of the cursor to navigate
016  * among returned "selections".
017  
018  * @common:target-namespace namespace="http://workshop.bea.com/SelectPath"
019  */
020 public class SelectPath implements com.bea.jws.WebService
021 
022     /**
023      * Declare a namespace corresponding to the namespace declared
024      * in the XML instance. The string here will be used as part of the
025      * XPath expression to ensure that the query finds namespace-qualified
026      * elements in the XML.
027      */
028     final static String m_namespaceDeclaration = 
029         "declare namespace xq='http://openuri.org/bea/samples/workshop/xmlBeans/xquery'";
030         
031     /**
032      * Test this method by copying the entire contents of the Employees.xml file and 
033      * pasting them in place of the &lt;AnyElement/&gt; element. Click the 
034      * selectByState button to execute the following expression, which selects 
035      * any employee elements whose state child element has a value of "WA":
036      <br/><br/>
037      
038      * &nbsp;$this/xq:employees/employee[address/state='WA']
039      
040      <br/><br/>
041      
042      * The portion of this expression in square brackets -- [address/state='WA'] -- 
043      * is known as a "predicate." The predicate filters items returned by the 
044      * expression to its immediate left. In other words, the first part of this 
045      * expression returns all of the employee elements, then the predicate 
046      * further filters those values to include only those whose address child element
047      * has a state child element with a value of "WA".
048      
049      * This method illustrates how you can query from an XmlObject instance
050      * with the selectPath method. Results of the query (if any) are
051      * returned in an XmlObject array.
052      
053      * @common:operation
054      */
055     public XmlObject[] selectByState(XmlObject empDoc)
056     {
057         /* 
058          * Create an XmlObject array to contain the results of the query. 
059          */
060         XmlObject[] resultArray = null;
061         
062         /* A variable for the XQuery path expression. */
063         String queryExpression = "$this/xq:employees/xq:employee[xq:address/xq:state='WA']";
064 
065         try
066         {
067             /* 
068              * Perform the query, combining the namespace declaration and the rest of query 
069              * expression.
070              */
071             resultArray = empDoc.selectPath(m_namespaceDeclaration + queryExpression);        
072         }catch(Exception e)
073         {
074             System.out.println(e.getLocalizedMessage());
075         }
076         /* 
077          * Return the array of results. Note that the returned results are contained 
078          * in an XmlObject element -- not an employee element.
079          */
080         return resultArray;
081     }
082 
083     /**
084      * Test this method by copying the entire contents of the Employees.xml file and 
085      * pasting them in place of the &lt;AnyElement/&gt; element. Click the 
086      * selectWorkPhonesAttr button to execute the following expression, which selects any 
087      * phone elements whose location attribute value is "work":
088      <br/><br/>
089      
090      * &nbsp;$this/xq:employees/employee/phone[@location='work']
091      
092      <br/><br/>
093      
094      * As with the selectByState method, this method
095      * uses a path expression and predicate to specify the requested XML.
096      
097      * This method illustrates how you can query from an XmlCursor instance
098      * with the selectPath method. Unlike the selectByState example, the results of 
099      * this query (if any) are managed by the cursor from which selectPath
100      * is called. Query results are available as "selections" in the cursor.
101      * You navigate among them with methods such as XmlCursor.toNextSelection.
102      
103      * @common:operation
104      */
105     public XmlObject selectWorkPhonesAttr(XmlObject empDoc)
106     {
107         // Add a cursor to the incoming XML.
108         XmlCursor empCursor = empDoc.newCursor();
109         
110         // Create a new XmlObject instance in which to return the results of the query.
111         XmlObject resultXml = XmlObject.Factory.newInstance();
112         
113         /* 
114          * Add a cursor to the new object; each of the returned results will be
115          * copied to the location of this cursor. In other words, the XML 
116          * will be copied from cursor located in one XmlObject to a cursor located
117          * in another.
118          */
119         XmlCursor resultCursor = resultXml.newCursor();
120         
121         /* 
122          * Move the result cursor to a location that's valid for receiving XML
123          * copied from the set of results. When first inserted, the cursor is just 
124          * outside (or "left of") the STARTDOC token -- or outside the XML. This
125          * call to toFirstToken moves it to a location between the STARTDOC and 
126          * ENDDOC, where XML can be inserted.
127          */
128         resultCursor.toFirstContentToken();
129         
130         // Create a variable with the query expression.
131         String queryExpression = "$this/xq:employees/xq:employee/xq:phone[@location='work']";
132 
133         try
134         {
135             // Execute the query.
136             empCursor.selectPath(m_namespaceDeclaration + queryExpression);
137             /* 
138              * Loop through the list of selections. For each selection,
139              * copy its value to the location of a cursor in another 
140              * XmlObject.
141              */
142             while (empCursor.toNextSelection())
143             {
144                 empCursor.copyXml(resultCursor);
145             }
146         }catch(Exception e)
147         {
148             System.out.println(e.getLocalizedMessage());
149         }
150         // Dispose of the query cursor.
151         empCursor.dispose();
152         // Return the XmlObject instance that now contains the results of the query.
153         return resultXml;
154     }
155 
156     /**
157      * Test this method by copying the entire contents of the Employees.xml file and 
158      * pasting them in place of the &lt;AnyElement/&gt; element. Click the 
159      * selectEmpsByStateFLWR button to execute the following expression, which selects any 
160      * employee elements whose location state element value is "WA":
161      <br/><br/>
162      
163      * &nbsp;for $e in $this/xq:employees/employee<br/>
164      * &nbsp;&nbsp;let $s := $e/address/state<br/>
165      * &nbsp;&nbsp;where $s = 'WA'<br/>
166      * &nbsp;&nbsp;return $e<br/>
167      <br/><br/>
168      
169      * This method's expression illustrates a FLWR (pronounced "flower") expression.
170      * The letters in the acronym stand for "for... let... where... return". As you
171      * can probably imagine, a FLWR expression is a way to loop through XML, 
172      * binding variables and evaluating based on the variables. This is very similar
173      * to loops in Java.
174      
175      * Compare the results of this method with the results of the 
176      * selectEmpsByStateFLWR method in the SimpleExpressions web service. That
177      * method uses the execQuery method to execute the expression, while this one
178      * uses selectPath.
179      
180      * @common:operation
181      */
182     public XmlObject[] selectEmpsByStateFLWR(XmlObject empDoc)
183     {
184         XmlObject[] resultArray = null;
185         /*
186          * This expression loops through the employee elements, querying for the
187          * state elements whose value is "WA", then returning the results.
188          */        
189         String queryExpression = 
190             "for $e in $this/xq:employees/xq:employee " +
191                 "let $s := $e/xq:address/xq:state " +
192                 "where $s = 'WA' " +
193                 "return $e";
194         try
195         {
196             // Execute the expression.
197             resultArray = empDoc.selectPath(m_namespaceDeclaration + queryExpression);
198         }catch(Exception e)
199         {
200             System.out.println(e.getLocalizedMessage());
201         }
202         return resultArray;
203     }
204 
205     /**
206      * Uses the selectPath method to execute the following
207      * expression against the incoming XML:
208      <br/><br/>
209      
210      * &nbsp;$this//xq:employee
211      
212      <br/><br/>
213      * If results are returned, you can move the cursor to the first of 
214      * those results with the toNextSelection method. The method then 
215      * uses the following path expression to get the name element for 
216      * each employee element:
217      <br/><br/>
218      
219      * &nbsp;$this//xq:name
220      
221      <br/><br/>
222      * The name element values
223      * are placed into a String array returned by the method.
224      <br/><br/>
225      * To test this method, paste the contents of the Employees.xml
226      * file between the getEmployees elements in the box on the
227      * Test XML tab of Test View.
228      
229      * @common:operation
230      */
231     public String[] getEmployees(XmlObject employees)
232     {
233         /**
234          * Create a cursor with which to execute query expressions.
235          * The cursor is inserted at the very beginning of the 
236          * incoming XML, then moved to the first element's start.
237          */
238         XmlCursor cursor = employees.newCursor();
239         cursor.toNextToken();
240         /**
241          * Execute the path expression, qualifying it with the 
242          * namespace declaration.
243          */
244         cursor.selectPath(m_namespaceDeclaration + "$this//xq:employee");
245         // Advance to the first selection in the list.
246         cursor.toNextSelection();
247         /**
248          * Create an array to hold the name element values.
249          */
250         String[] names = new String[cursor.getSelectionCount()];
251         /**
252          * Loop through the selections, querying for the name
253          * element, then placing the name element's value 
254          * in the String array.
255          */
256         for (int i = 0; i < cursor.getSelectionCount(); i++)
257         {
258             // An new cursor for the new query.
259             XmlCursor nameCursor = cursor.newCursor();
260             // Get the name element.
261             nameCursor.selectPath(m_namespaceDeclaration + 
262                 "$this/xq:name");
263             // Advance to the first selection.
264             nameCursor.toNextSelection();
265             /**
266              * Extract the name element's value and assign it
267              * to the array.
268              */  
269             names[i= nameCursor.getTextValue();
270             /**
271              * Advance to the next selection in the original set
272              * of results.
273              */
274             cursor.toNextSelection();
275         }
276         return names;
277     }
278