Introduction

This guide shows how to integrate the C++/Tree mapping generated by CodeSynthesis XSD with Berkeley DB XML. Berkeley DB XML is an embedded XML database which allows efficient storage and query of XML instance documents. CodeSynthesis XSD is a W3C XML Schema to C++ data binding compiler. The C++/Tree mapping allows you to manipulate the data stored in XML using objects that semantically correspond to your application domain rather than dealing with direct representations of XML. For an introduction to the Berkeley DB XML refer to the Berkeley DB XML Getting Started Guide. For an introduction to the C++/Tree mapping refer to the C++/Tree Mapping Getting Started Guide.

This guide describes the following four operations:

Our examples will be based on simple XML for book library. The XML Schema definition for the library is in library.xsd and is compiled by XSD to obtain library.hxx and library.cxx. A sample XML document is presented below:

<lib:catalog xmlns:lib="http://www.codesynthesis.com/library">
  <book available="true" id="ES">
    <isbn>20530902</isbn>
    <title>The Elements of Style</title>
    <genre>reference</genre>

    <author>
      <name>William Strunk, Jr.</name>
      <born>1869-07-01</born>
      <died>1946-09-26</died>
    </author>

    <author>
      <name>E.B. White</name>
      <born>1899-07-11</born>
      <died>1985-10-01</died>
    </author>
  </book>
</lib:catalog>
  

All C++ code fragments that are presented in this guide are available as a single program in driver.cxx. The complete example is available in the examples/cxx/tree/dbxml directory of the XSD distribution.

Note that due to the incomplete DOM API implementation provided by DB XML (as of version 2.3.10), the generated code and your application should be compiled with the DBXML_DOM macro defined in order to avoid using unsupported parts of the API.

Create Document from Object Model

In this step, we will programmatically create a book catalog with one book, save it into an XmlDocument object using one of the serialization functions generated by XSD ( catalog_ in our case), and store the XmlDocument object as a new document in the DB container:

XmlManager manager;
XmlContainer container (manager.createContainer ("new.bdbxml"));
XmlUpdateContext update_context (manager.createUpdateContext ());
XmlQueryContext context (manager.createQueryContext ());
context.setNamespace ("lib", "http://www.codesynthesis.com/library");

// Create a new catalog with one book.
//
catalog c;

book b (20530902,                        // ISBN
        title ("The Elements of Style"), // Title
        genre::reference,                // Genre
        "ES");                           // ID

author strunk ("William Strunk, Jr.", date (1869, 7, 1));
strunk.died (date (1946, 9, 26));

b.author ().push_back (strunk);
c.book ().push_back (b);

// Create a new XML document.
//
XmlDocument doc (manager.createDocument ());
doc.setName ("new.xml");

// Obtain its DOM representation and add the root element.
//
xercesc::DOMDocument& dom_doc (*doc.getContentAsDOM ());

dom_doc.appendChild (
  dom_doc.createElementNS (
    xml::string ("http://www.codesynthesis.com/library").c_str (),
    xml::string ("lib:catalog").c_str ()));

// Serialize the object model to the XML document. Also avoid
// re-initializing the Xerces-C++ runtime since XmlManager has
// it initialized.
//
catalog_ (dom_doc, c, xml_schema::flags::dont_initialize);

// Place the document into the container.
//
container.putDocument (doc, update_context);
  

If we now resolve the new.xml in the container and print its content, we will get:

<lib:catalog xmlns:lib="http://www.codesynthesis.com/library">
  <book available="true" id="ES">
    <isbn>20530902</isbn>
    <title>The Elements of Style</title>
    <genre>reference</genre>
    <author>
      <name>William Strunk, Jr.</name>
      <born>1869-07-01</born>
      <died>1946-09-26</died>
    </author>
  </book>
</lib:catalog>
  

Create Object Model from Document

Creating an object model from a document is a matter of obtaining XmlDocument object and passing its DOM representation to one of the parsing functions generated by XSD (catalog_ in our case):

// Resolve the document in the container.
//
XmlDocument doc (container.getDocument ("new.xml"));

// Create the object model from the document's DOM. Also avoid
// re-initializing the Xerces-C++ runtime since XmlManager has
// it initialized.
//
auto_ptr<catalog> c (catalog_ (*doc.getContentAsDOM (),
                               xml_schema::flags::dont_initialize));

cerr << *c << endl;
  

This code fragment prints:

book:
isbn: 20530902
title: The Elements of Style
genre: reference
author:
name: William Strunk, Jr.
born: 1869-07-01
died: 1946-09-26
available: 1
id: ES
  

Create Object Model from Document Fragment

The following code fragment looks up the book with id "ES" using XQuery. It then creates a book object from the resulting XmlValue:

string query ("collection('new.bdbxml')/lib:catalog/book[@id='ES']");

// Find "The Elements of Style".
//
XmlValue v;
XmlResults results (manager.query (query, context));

if (results.next (v))
{
  // Create an object model from the document fragment.
  //
  auto_ptr<book> b (
    new book (
      *static_cast<xercesc::DOMElement*> (v.asNode ())));

  cerr << *b << endl;
}
  

This code fragment prints:

isbn: 20530902
title: The Elements of Style
genre: reference
author:
name: William Strunk, Jr.
born: 1869-07-01
died: 1946-09-26
available: 1
id: ES
  

Note that we had to perform a static_cast from xercesc::DOMNode returned by the XmlValue::asNode member function to xercesc::DOMElement. This is safe since we know that in our schema books are represented as XML elements.

Update Document Fragment from Object Model

Analogous to the create case, the following code fragment looks up the book with id "ES" using XQuery. It then creates a book object from the resulting XmlValue, adds another author, changes the availability status, and saves the changes back to the XmlValue object:

string query ("collection('new.bdbxml')/lib:catalog/book[@id='ES']");

// Find "The Elements of Style".
//
XmlValue v;
XmlResults results (manager.query (query, context));

if (results.next (v))
{
  // Create an object model from the document fragment.
  //
  auto_ptr<book> b (
    new book (
      *static_cast<xercesc::DOMElement*> (v.asNode ())));

  // Add another author, change the availability status.
  //
  author white ("E.B. White", date (1899, 7, 11));
  white.died (date (1985, 10, 1));

  b->author ().push_back (white);
  b->available (false);

  // Update the document fragment from the object model.
  //
  *static_cast<xercesc::DOMElement*> (v.asNode ()) << *b;

  // Update the document in the container.
  //
  XmlDocument doc (v.asDocument ());
  container.updateDocument (doc, update_context);
}
  

If we now resolve the new.xml in the container and print its content, we will get:

<lib:catalog xmlns:lib="http://www.codesynthesis.com/library">
  <book available="false" id="ES">
    <isbn>20530902</isbn>
    <title>The Elements of Style</title>
    <genre>reference</genre>
    <author>
      <name>William Strunk, Jr.</name>
      <born>1869-07-01</born>
      <died>1946-09-26</died>
    </author>
    <author>
      <name>E.B. White</name>
      <born>1899-07-11</born>
      <died>1985-10-01</died>
    </author>
  </book>
</lib:catalog>