# 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 }`