# 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 a direct representation 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 Quick Guide.

This guide describes the following four operations:

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

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:book-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:book-catalog>

All code fragments that are presented in this guide are available as a complete program in driver.cxx. You may also choose to download all files mentioned in this document as a single archive: library-dbxml.tar.gz or library-dbxml.zip.

# Create Document from Object Representation

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 ( `book_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.", "1869-07-01");
    strunk.died ("1946-09-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:book-catalog").c_str ()));

    // Serialize the object representation to the XML document.
    //
    book_catalog (dom_doc, c);

    // 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:book-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:book-catalog>

# Create Object Representation from Document

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

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

    // Create the object representation from the document's DOM.
    //
    auto_ptr<catalog> c (book_catalog (*doc.getContentAsDOM ()));

    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 Representation from Document Fragment

Creating object representations from document fragments is done using the `from_value_e` and `from_value_a` helper functions defined in the xsd-dbxml.hxx header. The `from_value_e` function is used to create an object from an element fragment referenced by `XmlValue` while `from_value_a` is used for attribute fragments.

The following code 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:book-catalog/book[@id='ES']");

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

    if (results.next (v))
    {
      // Create an object representation from the document fragment.
      //
      auto_ptr<book> b (tree::from_value_e<book> (v));

      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

# Update Document Fragment from Object Representation

Analogous to the create case, updating document fragments from object representations is done using the `to_value_e` and `to_value_a` helper functions defined in the xsd-dbxml.hxx header. The `to_value_e` function is used to update an element fragment referenced by `XmlValue` while `to_value_a` is used for attribute fragments.

The following code 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:book-catalog/book[@id='ES']");

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

    if (results.next (v))
    {
      // Create an object representation from the document fragment.
      //
      auto_ptr<book> b (tree::from_value_e<book> (v));

      // Add another author, change the availability status.
      //
      author white ("E.B. White", "1899-07-11");
      white.died ("1985-10-01");

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

      // Update the document fragment from the object representation.
      //
      tree::to_value_e (v, *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:book-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:book-catalog>