Original URL: https://www.theregister.com/2007/07/18/berkeley_db_xml/
An embedded XML Database: Oracle Berkeley DB XML
There is more to life than RDBMS
Posted in Software, 18th July 2007 11:31 GMT
Tutorial Storing an XML document in a relational database has its limitations. XML’s hierarchical structures do not map well to relational database structures. That’s where an embeddable (non-relational) XML database has advantages over a relational database.
Oracle database (since Oracle 9i database R2) provides the Oracle XML DB feature to store and query XML documents in an XMLType
data type column, but you still need a DBA to manage the Oracle database.
Oracle Berkeley DB XML, however, is an embeddable XML database specifically designed for storing and retrieving XML documents. Berkeley DB (BDB) was developed at U.C Berkeley and acquired by Oracle in February 2006; Oracle Berkeley DB XML provides efficient querying of XML documents using Xquery and does not require much administration. XQuery is an SQL-like query language for XML and is based on XPath. BDB XML supports XQuery 1.0 and XPath 2.0 specifications. Oracle Berkeley DB XML is built on top of the embeddable Oracle Berkeley DB database and inherits all the features of the database.
Installing Oracle Berkeley DB XML
We need to download Oracle Berkeley DB XML 2.3.10 Windows Installer. To install Oracle BDB XML, double-click on the dbxml-2.3.10.msi file. The Installer gets started. Click on Next.
Accept the Open Source License and click on Next. Select the default installation folder, C:\Program Files\Oracle\Berkeley DB XML 2.3.10
, and click on Next. Select the default Berkeley DB XML features and click on Next.
Berkeley DB XML requires some environment variables (CLASSPATH
and PATH
) to be modified. Select the “Set the values in the environment variables” checkbox and click on Next. Click on the Install button to install Berkeley DB XML. Click on the Finish button. Berkeley DB XML may be accessed from either the command line shell or with a Java API.
Using the Command Shell
The dbxml
shell may be started with the dbxml
command:
C:/>dbxml
The following prompt gets displayed:
dbxml>
Berkeley DB XML commands may be specified at the dbxml
command prompt. Let’s first create a container to store XML documents using the createContainer
command:
dbxml>createContainer catalog.dbxml
A node storage container with nodes indexed gets created and opened (see Figure 3):
The BDB XML database is just a .dbxml
file created in the directory in which the dbxml
command was issued.
Adding XML Documents
Next, we’ll add XML documents to the container, using the putDocument
command. For example, add an XML document that represents a catalog entry:
dbxml>putDocument catalog1 '<catalog title="Oracle Magazine" publisher="Oracle Publishing"> … </catalog>' s
Single quotes are used for any command parameters that span multiple lines or contain spaces. The character ‘s’ used to terminate the command indicates that the XML document is added using a string.
Similarly add another catalog ‘catalog2’. The XML documents added may be retrieved with the getDocuments
command:
dbxml>getDocuments
The documents retrieved may be output to stdout with the print
command:
dbxml>print
Querying XML Documents with Xquery
XQuery queries retrieve subsets of data similarly to the use of SELECT statement in SQL. Each query has two parts; the first part identifies the set of documents to be queried using an XQuery navigation function such as collection()
or doc()
. The collection()
function is used to navigate to a container. The doc()
function may be used to navigate to a specified XML document in a container. As an example of a query select all the article titles in the catalog.dbxml
container using the query command:
dbxml>query 'collection("catalog.dbxml")/catalog/journal/article/title/text()'
To output the results of the query use the print
command:
dbxml>print Using Bind Variables From Application Express to XE
Modifying XML Documents
The Oracle BDB XML command shell provides various commands such as append
, insertAfter
and insertBefore
to modify an XML document in the database. The append
command won’t append an attribute if the context has not been set. The query expression for modifying nodes should be relative; it should navigate from the context item “.” rather than evaluating an expression with the collection()
or doc()
function. The context is set prior to the modifications with the query
command. For example, set the context to the catalog.dbxml
container:
dbxml> query 'collection("catalog.dbxml")'
Having set the context we may run an append
command. As an example add an ‘article’ node:
dbxml> append './catalog/journal[article/title="Using Bind Variables"]' 'element' 'article' '<title>Commanding ASM</title><author>Arup Nanda</author>'
Retrieve the modified “catalog1” document with the getDocuments
command and output the document with the print
command – see Figure 6.
Using the Berkeley DB XML API
In BDB XML documents are stored in containers. Containers are of two types; Wholedoc containers and Node containers. A Wholedoc container stores the complete XML document without any modifications to line breaks or whitespaces. In a Node container, XML documents are stored as nodes. BDB XML also stores information about reassembling an XML document from the nodes stored in the database. The Node container is preferred and is the default type. A comparison of Node container and Wholedoc container is discussed in the Table below:
Container Type | Storage Mode | Query Performance | Load Performance | Application |
---|---|---|---|---|
Node Container | XML document stored in nodes | Faster to query | Lower load performance | Use Node container if faster query performance is required. Use Node container if document size is more than 1MB. |
Wholedoc Container | Whole XML document stored | Lower query performance, because complete document has to be navigated | Faster document loading, because an XML document does not have to be deconstructed into nodes | Use Wholedoc container if load performance is more important than query performance. Use Wholedoc container if document is relatively small and requires to be frequently retrieved. |
An XmlManager
object is used to manage many of the objects used in a BDB XML application, including managing an XmlContainer
and preparing and running XQuery queries. Create an XmlManager
object and set the default container type to be Node container.
XmlManager xmlManager = new XmlManager(); xmlManager.setDefaultContainerType(XmlContainer.NodeContainer);
Next, create a container, catalog.dbxml
. The container is the BDB XML database:
XmlContainer xmlContainer = xmlManager.createContainer("catalog.dbxml");
Adding XML Documents
Similar to the putDocument
shell command, the BDB XML API provides a method putDocument()
to store an XML document in a database. Create a String
object that represents an XML document and specify a document name:
String docString =”<catalog> … </catalog>”; String docName = "catalog1";
Create an XmlUpdateContext
object. An XmlUpdateContext
object represents the context within which update operations are performed in a container:
XmlUpdateContext updateContext = xmlManager.createUpdateContext();
Now store the XML document:
xmlContainer.putDocument(docName, docString, updateContext, null);
Similarly, add another XML document as shown in BDBXML.java in the resources.zip file.
Querying XML Documents with Xquery
Next, we’ll query the XML documents in the catalog.dbxml
BDXML database using XQuery. First, we create an XmlQueryContext
object representing the context within which an XML document in a container is queried:
XmlQueryContext context = xmlManager.createQueryContext();
As an example, retrieve the values of all the titles in the BDB XML database. Specify the query string that represents the XQuery expression for the query:
String query = "collection('catalog.dbxml')/catalog/journal/article/title/text()";
Now compile the XQuery expression:
XmlQueryExpression qe = xmlManager.prepare(query, context);
Next, evaluate the XQuery expression:
XmlResults results = qe.execute(context);
Iterate over the results and output the titles retrieved:
while (results.hasNext()) { XmlValue xmlValue = results.next(); System.out.println(xmlValue.asString()); }
The output from the query is as follows:
Using Bind Variables From Application Express to XE
Modifying XML Documents
Next, we’ll modify an XML document in the database. BDB XML API provides the XmlModify
class to modify an XML document and the procedure to modify an XML document is as follows:
- Create an XmlModify object.
- Select the nodes to be modified.
- Specify the modification steps. Modifications are performed in the order specified.
- Run the modifications in the context of an XML document or a set of XML documents.
As in the previous sections, first create an XmlModify
object, an XmlQueryContext
object, and an XmlUpdateContext
object. As an example, add a section
attribute to the article
element. Select the article node using an XQuery expression:
XmlQueryExpression select = xmlManager.prepare("/catalog/journal/article",qc);
Use the addAppendStep()
method to append the section
attribute to article
element. The type of an object to be added may be an element (represented with XmlModify.Element
), an attribute (XmlModify.Attribute
), a comment (XmlModify.Comment
), text (XmlModify.Text
), or a processing instruction (XmlModify.ProcessingInstruction
). We’ll add a section
attribute with value “Developer”:
mod.addAppendStep(select, XmlModify.Attribute, "section", "Developer");
Next, add a journal
element after the journal
element in catalog1 document. Select the journal
node in catalog1 document:
XmlQueryExpression select = xmlManager.prepare("/catalog/journal [article/title='Using Bind Variables']",qc);
Specify the element content to be added:
String objectContent = "<article>…</article>";
Add the journal
element using the addInsertAfterStep()
method:
mod.addInsertAfterStep(select, XmlModify.Element, "journal",objectContent);
The modifications are not complete yet. Obtain the XML document in which the modification is to be performed:
XmlDocument xmlDocument = xmlContainer.getDocument("catalog1");
Obtain the XmlValue
object for the XML document and run the modifications:
XmlValue xmlValue = new XmlValue(xmlDocument); mod.execute(xmlValue, qc, uc);
Similarly, elements may be updated, renamed, and deleted.
The Berkeley DB XML database has advantages over a relational database for storing complete XML documents that may be queried, modified, and updated without having to retrieve the documents from the database. ®