XML-Formatted Bakery Documents

Contents

Introduction

The Document/View With Bakery page explains how to derive a Document class for your application. But Bakery::Document doesn't help you to organise or parse the data in the file. And f you achieve that by using a custom data format then other applications will not be able to easily use the same document. To solve this problem, the Bakery::Document_XML class helps you to use an XML format to store your data. This has the following advantages:

Create the Document class

Derive a Document class from Bakery::Document_XML. You don't need to override load_after() and save_after(), because Document_XML can do that for XML documents in general.

e.g.

class DocExample : public Bakery::Document_XML
{
public:
  DocExample();
  virtual ~DocExample();

  void set_something(const std::string& strSomething);
  std::string get_something();

protected:
  xmlpp::Node* get_node_something(); //Gets 
};

As in the other examples, you should specify the file extension in the constructor. But you should also specify the name of the XML file's DTD, and the name of the top-level XML node. These will be used to create new empty Documents.

DocExample::DocExample()
{
  set_file_extension("bakery_example_xml");
 
  set_DTD_Name("example_xml_doc.dtd");
  set_DTD_RootNodeName("example_xml_doc");
}

As in the other examples, when you implement methods like set_something(), which changes data in your document, you should call Document::set_modified(true).

In this example there is also a get_node_something() convenience method, just to reduce code duplication. Notice that we use the libxml++ Node class from the xmlpp namespace.

void DocExample::set_something(const std::string& strSomething)
{
  try
  {
    set_node_attribute_value(get_node_something(), "someval", strSomething);
    set_modified();
  }
  catch(const std::exception& ex)
  {
    //HandleError(ex); 
  }
}

std::string DocExample::get_something()
{
  std::string strValue;

  try
  {
    strValue = get_node_attribute_value(get_node_something(), "someval");
  }
  catch(const std::exception& ex)
  {
    //HandleError(ex); 
  }

  return strValue;
}

xmlpp::Node* DocExample::get_node_something()
{
  try
  { 
    xmlpp::Node* nodeRoot = get_node_document();
    return get_node_child_named_with_add(nodeRoot, "something");
  }
  catch(const std::exception& ex)
  {
    //HandleError(ex);
    return 0;
  }
}

You just need to use the libxml++ xmlpp::DomParser API, along with some convenience methods in Bakery::Document_XML, to navigate, read, and build your document. Bakery::Document_XML will take care of actually reading the XML into memory and writing it back to disk at the appropriate time.

Copyright © 2001, Murray Cumming. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.