To add a document to a container, you use
XmlContainer::putDocument()
.
When you use this method, you must:
Somehow obtain the document that you want to put into
the container. To do this, you can create an input stream
to the content or load the XML document into a string object.
Alternatively, you can load the document into
an XmlDocument
object
and then provide the
XmlDocument
object to
XmlContainer::putDocument()
.
When you do this, you can provide the document to the
XmlDocument
object using an
input stream or string, or you can construct the
document using an event writer.
Provide a name for the document. This name must be unique or
BDB XML will throw
XmlException::UNIQUE_ERROR
.
If you are using an XmlDocument
object to add the document, use
XmlDocument::setName()
to set the document's name. Otherwise, you can set the name
directly on the call to
XmlContainer::putDocument()
.
Note that if you do not want to explicitly set a name for
the document, you can
set a flag, DBXML_GEN_NAME
,
on the call to XmlContainer::putDocument()
.
This causes BDB XML to generate a unique name for you. The
name that it generates is a concatenation of a unique
value, an underscore, and the value that you provide for the document's
name, if any. For example:
myDocName_a
where myDocName
is the name that you set
for the document and a
is the unique value generated
by BDB XML.
If you do not set a name for the document, but you do
specify that a unique name is to be generated, then
dbxml
is used as the name's prefix.
dbxml_b
If you do not set a name for the document and if you do not
use
DBXML_GEN_NAME
,
then BDB XML throws
XmlException::UNIQUE_ERROR
.
Create an XmlUpdateContext
object.
This object encapsulates the context within which the
container is updated. Reusing the same object for a series
of puts against the same container can improve your
container's write performance.
Note that the content that you supply to
XmlContainer::putDocument()
is read and validated. By default, this includes any schema or
DTDs that the document might reference. Since this can cause
you some performance issues, you can cause BDB XML to only
examine the document body itself by
passng the DBXML_WELL_FORMED_ONLY
flag to
XmlContainer::putDocument()
.
However, using this
flag
cause parsing errors if the document references
information that might have come from a schema or DTD.
Further, note that while your documents are stored in the container with their shared text entities (if any) as-is, the underlying XML parser does attempt to expand them for indexing purposes. Therefore, you must make sure that any entities contained in your documents are resolvable at load time.
For example, to add a document that is held in a string:
#include "DbXml.hpp" ... using namespace DbXml; int main(void) { // The document std::string docString = "<a_node><b_node>Some text</b_node></a_node>"; // The document's name. std::string docName = "testDoc1"; // Get a manager object. XmlManager myManager; // The manager is closed when // it goes out of scope. // Load the document in its entirety. The document's formatting is // preserved. myManager.setDefaultContainerType(XmlContainer::WholedocContainer); // Open the container. The container is closed when it goes // out of scope. XmlContainer myContainer = myManager.openContainer("container.bdbxml"); // Need an update context for the put. XmlUpdateContext theContext = myManager.createUpdateContext(); // Put the document try { myContainer.putDocument(docName, // The document's name docString, // The actual document, // in a string. theContext, // The update context // (required). 0); // Put flags. } catch (XmlException &e) { // Error handling goes here. You may want to check // for XmlException::UNIQUE_ERROR, which is raised // if a document with that name already exists in // the container. If this exception is thrown, // try the put again with a different name. } return(0); }
To load the document from an input stream, the code is identical except that
you use the appropriate method on XmlManager
to
obtain the stream. For example, to load an XmlDocument directly from a file
on disk:
#include "DbXml.hpp" ... using namespace DbXml; int main(void) { // The document std::string fileName = "/export/testdoc1.xml"; // The document's name. std::string docName = "testDoc1"; // Get a manager object. XmlManager myManager; // The manager is closed when // it goes out of scope. // Load the document in its entirety. The document's formatting is // preserved. myManager.setDefaultContainerType(XmlContainer::WholedocContainer); // Open the container. The container is closed when it goes // out of scope. XmlContainer myContainer = myManager.openContainer("container.bdbxml"); // Need an update context for the put. XmlUpdateContext theContext = myManager.createUpdateContext(); try { // Get the input stream. XmlInputStream *theStream = myManager.createLocalFileInputStream(fileName); // Put the document myContainer.putDocument(docName, // The document's name theStream, // The actual document. theContext, // The update context // (required). 0); // Put flags. } catch (XmlException &e) { // Error handling goes here. You may want to check // for XmlException::UNIQUE_ERROR, which is raised // if a document with that name already exists in // the container. If this exception is thrown, // try the put again with a different name. } return(0); }