C++/Tree Mapping and Berkeley DB XML Integration Guide
Keywords: xsd,xml,schema,c++,mapping,data,binding,berkeley,db,dbxml

# 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:

- Create a new document in DB from an object model
- Create an object model from a document in DB
- Create an object model from a document fragment in DB
- Update a document fragment in DB from an object model

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>