When you perform a query against BDB XML, you receive a results set in the form of an XmlResults object. To examine the results, you iterate over this result set, retrieving each element of the set as an XmlValue object.
Once you have an individual result element, you can obtain the data encapsulated in the XmlValue object in a number of ways. For example, you can obtain the information as a string object using XmlValue.asString(). Alternatively, you could obtain the data as an XmlDocument object using XmlValue.asDocument().
It is also possible to use DOM-like navigation on the XmlValue object since that class offers navigational methods such as XmlValue.getFirstChild(), XmlValue.getNextSibling(), XmlValue.getAttributes(), and so forth. For details on these and other XmlValue attributes, see the BDB XML Javadoc.
For example, the following code fragment performs a query and then loops over the result set, obtaining and displaying the document's name from an XmlDocument object before displaying the document itself.
package dbxml.gettingStarted; import com.sleepycat.dbxml.XmlContainer; import com.sleepycat.dbxml.XmlException; import com.sleepycat.dbxml.XmlManager; import com.sleepycat.dbxml.XmlQueryContext; import com.sleepycat.dbxml.XmlResults; import com.sleepycat.dbxml.XmlValue; ... XmlManager myManager = null; XmlContainer myContainer = null; ... try { // Get a manager object. myManager = new XmlManager(); // Open a container myContainer = myManager.openContainer("exampleData.dbxml"); // Get a query context XmlQueryContext context = myManager.createQueryContext(); // Declare a namespace context.setNamespace("fruits", "http://groceryItem.dbxml/fruits"); // Declare the query string. Find all the product documents // in the fruits namespace. String myQuery = "collection('exampleData.dbxml')/fruits:product"; // Perform the query. XmlResults results = myManager.query(myQuery, context); // Show the size of the result set String message = "Found "; message += results.size() + " documents for query: '"; message += myQuery + "'\n"; System.out.println(message); // Display the result set XmlValue value = results.next(); while (value != null) { XmlDocument theDoc = value.asDocument(); String docName = theDoc.getName(); String docString = value.asString(); message = "Document "; message += theDoc.getName() + ":\n"; message += value.asString(); message += "===============================\n"; System.out.println(message); value = results.next(); } } catch (XmlException e) { // Error handling goes here. } finally { try { if (myContainer != null) { myContainer.close(); } if (myManager != null) { myManager.close(); } } catch (XmlException ce) { // Exception handling goes here }
It is frequently useful to retrieve a document from BDB XML and then perform follow-on queries to retrieve individual values from the document itself. You do this by creating and executing a query, except that you pass the specific XmlValue object that you want to query to the XmlQueryExpression.execute() method. You must then iterate over a result set exactly as you would when retrieving information from a container.
For example, suppose you have an address book product that manages individual contacts using XML documents such as:
<contact> <familiarName>John</familiarName> <surname>Doe</surname> <phone work="555 555 5555" home="555 666 777" /> <address> <street>1122 Somewhere Lane</street> <city>Nowhere</city> <state>Minnesota</state> <zipcode>11111</zipcode> </address> </contact>
Then you could retrieve individual documents and pull data off of them like this:
package dbxml.gettingStarted; import com.sleepycat.dbxml.XmlContainer; import com.sleepycat.dbxml.XmlException; import com.sleepycat.dbxml.XmlManager; import com.sleepycat.dbxml.XmlQueryContext; import com.sleepycat.dbxml.XmlResults; import com.sleepycat.dbxml.XmlValue; ... XmlManager myManager = null; XmlContainer myContainer = null; ... try { // Get a manager object. myManager = new XmlManager(); // Open a container myContainer = myManager.openContainer("exampleData.dbxml"); // Declare the query string. Retrieves all the documents // for people with the last name 'Doe'. String myQuery = "collection('exampleData.dbxml')/contact"; // Query to get the familiar name from the // document. String fn = "distinct-values(/contact/familiarName)"; // Query to get the surname from the // document. String sn = "distinct-values(/contact/surname)"; // Work phone number String wrkPhone = "distinct-values(/contact/phone/@work)"; // Get the context for the XmlManager query XmlQueryContext managerContext = myManager.createQueryContext(); // Get a context for the document queries XmlQueryContext documentContext = myManager.createQueryContext(); // Prepare the XmlManager query XmlQueryExpression managerQuery = myManager.prepare(myQuery, managerContext); // Prepare the individual document queries XmlQueryExpression fnExpr = myManager.prepare(fn, documentContext); XmlQueryExpression snExpr = myManager.prepare(sn, documentContext); XmlQueryExpression wrkPhoneExpr = myManager.prepare(wrkPhone, documentContext); // Perform the query. XmlResults results = managerQuery.execute(managerContext, 0); // Display the result set XmlValue value = results.next(); while (value != null) { // Get the individual values XmlResults fnResults = fnExpr.execute(value, documentContext); XmlResults snResults = snExpr.execute(value, documentContext); XmlResults phoneResults = wrkPhoneExpr.execute(value, documentContext); String fnString; if (fnResults.size() > 0) { XmlValue fnValue = fnResults.next(); fnString = fnValue.asString(); } else { continue; } String snString; if (snResults.size() > 0) { XmlValue snValue = snResults.next(); snString = snValue.asString(); } else { continue; } String phoneString; if (phoneResults.size() > 0) { XmlValue phoneValue = phoneResults.next(); phoneString = phoneValue.asString(); } else { continue; } String message = fnString + " " + snString + ": " + phoneString; System.out.println(message); value = results.next(); } catch (XmlException e) { // Error handling goes here. } finally { try { if (myContainer != null) { myContainer.close(); } if (myManager != null) { myManager.close(); } } catch (XmlException ce) { // Exception handling goes here }
Note that you can use the same basic mechanism to pull information out of very long documents, except that in this case you need to maintain the query's focus; that is, the location in the document that the result set item is referencing. For example suppose you have a document with 2,000 contact nodes and you want to get the name attribute from some particular contact in the document.
There are several ways to perform this query. You could, for example, ask for the node based on the value of some other attribute or element in the node:
/document/contact[category='personal']
Or you could create a result set that holds all of the document's contact nodes:
/document/contact
Regardless of how you get your result set, you can then go ahead and query each value in the result set for information contained in the value. To do this:
Make sure you use the same XmlQueryContext object as you used to generate the result set in the first place. This object will track the result item's focus (that is, the node's location in the larger document — the self axis.) for you.
Iterate over the result set as normal.
Query for document information as described above. However, in this case change the query so that you reference the self access. That is, for the surname query described above, you would use the following query instead so as to reference nodes relative to the current node (notice the self-access (.) in use in the following query):
distinct-values(./surname)
When you retrieve a document from BDB XML, there are two ways to examine the metadata associated with that document. The first is to use XmlDocument.getMetaData(). Use this form if you want to examine the value for a specific metadata value.
The second way to examine metadata is to obtain an XmlMetaDataIterator object using XmlDocument.getMetaDataIterator(). You can use this mechanism to loop over and display every piece of metadata associated with the document.
For example:
package dbxml.gettingStarted; import com.sleepycat.dbxml.XmlContainer; import com.sleepycat.dbxml.XmlException; import com.sleepycat.dbxml.XmlManager; import com.sleepycat.dbxml.XmlMetaData; import com.sleepycat.dbxml.XmlMetaDataIterator; import com.sleepycat.dbxml.XmlQueryContext; import com.sleepycat.dbxml.XmlResults; import com.sleepycat.dbxml.XmlValue; ... XmlManager myManager = null; XmlContainer myContainer = null; ... try { // Get a manager object. myManager = new XmlManager(); // Open a container myContainer = myManager.openContainer("exampleData.dbxml"); // Get a query context XmlQueryContext context = myManager.createQueryContext(); // Declare a namespace context.setNamespace("fruits", "http://groceryItem.dbxml/fruits"); // Declare the query string. Find all the product documents // in the fruits namespace. String myQuery = "collection('exampleData.dbxml')/fruits:product"; // Perform the query. XmlResults results = myManager.query(myQuery, context); // Display the result set XmlValue value = results.next(); while (value != null) { XmlDocument theDoc = value.asDocument(); String docName = theDoc.getName(); String docString = value.asString(); // Display all of the metadata set for this document XmlMetaDataIterator mdi = theDoc.getMetaDataIterator(); String message = "For document '" + theDoc.getName(); message += "' found metadata:"; System.out.println(message); XmlMetaData md = mdi.next(); while (md != null) { message = "\tURI: " + md.get_uri(); message += ", attribute name: " + md.get_name(); message += ", value: " + md.get_value() + "\n"; System.out.println(message); md = mdi.next(); } // Display a single metadata value: String URI = "http://dbxmlExamples/timestamp"; String attrName = "timeStamp"; XmlValue newRetValue = null; boolean gotResult = theDoc.getMetaData(URI, attrName, newRetValue); if (gotResult) { message = "For URI: " + URI + ", and attribute: " + attrName; message += ", found: " + newRetValue + "\n"; System.out.println(message); } message = "===============================\n"; System.out.println(message); value = results.next(); } } catch (XmlException e) { // Error handling goes here. } finally { try { if (myContainer != null) { myContainer.close(); } if (myManager != null) { myManager.close(); } } catch (XmlException ce) { // Exception handling goes here }