Skip to content

DOM Persistence

Gary edited this page Aug 27, 2014 · 1 revision

Table of Contents

You can persist application data with the DomXmlWriter and DomXmlReader classes.

It's not very useful to create application data if it can't be persisted, that is, stored in some form that can be read back into the application later for further work. ATF provides classes to write application data to XML and then read it back into the application. It is easiest to do this if your DOM uses an XML Schema for its type definitions and a schema loader based on XmlSchemaTypeLoader.

Writing Application Data

Use the DomXmlWriter class to format all the information in a DomNode tree in XML and write it to an output stream. The stream you write to is often a file, but can be any output device. Reading and writing XML files for the application is usually part of your implementation of the ATF IDocument interface, which is ATF's interface for documents. To learn more about this interface and documents, see Documents in ATF.

The following code for the Save() method comes from the ATF Fsm Editor Sample, but is nearly the same in all the ATF samples.

public void Save(IDocument document, Uri uri)
{
    string filePath = uri.LocalPath;
    FileMode fileMode = File.Exists(filePath) ? FileMode.Truncate : FileMode.OpenOrCreate;
    using (FileStream stream = new FileStream(filePath, fileMode))
    {
        DomXmlWriter writer = new DomXmlWriter(m_schemaLoader.TypeCollection);
        Document fsmDocument = (Document)document;
        writer.Write(fsmDocument.DomNode, stream, uri);
    }
}

First, this example obtains the path of a new or existing file from the uri argument. It then creates a new instance of DomXmlWriter with the type collection from the schema loader. The writer uses this type information so that it can transfer all the application data to XML appropriately, and it also uses type names to format its XML tags. Next, Save() casts the incoming IDocument parameter to the application's document type (Document), which is a DOM adapter, so that the DomNodeAdapter.DomNode property can be used to get the root DomNode. Finally, the DomXmlWriter.Write() method, given the root of the DOM node tree, writes all the DomNode's data to the open FileStream.

Reading Application Data

Use the DomXmlReader class to read XML content (written by DomXmlWriter) from an input stream and create a DomNode tree. The new tree has exactly the same information as the original DOM node tree written by DomXmlWriter. The stream you read from is often a file, but can be any input device. To read XML content from a stream, you need an instance of your schema loader, derived from XmlSchemaTypeLoader.

The following code for the Open() method comes from the ATF Fsm Editor Sample, but is almost the same in all ATF samples:

public IDocument Open(Uri uri)
{
    DomNode node = null;
    string filePath = uri.LocalPath;
    string fileName = Path.GetFileName(filePath);

    if (File.Exists(filePath))
    {
        // read existing document using standard XML reader
        using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            DomXmlReader reader = new DomXmlReader(m_schemaLoader);
            node = reader.Read(stream, uri);
        }
    }
    else
    {
        // create new document by creating a Dom node of the root type defined by the schema
        node = new DomNode(Schema.fsmType.Type, Schema.fsmRootElement);
        // create an empty root prototype folder
        node.SetChild(
            Schema.fsmType.prototypeFolderChild,
                new DomNode(Schema.prototypeFolderType.Type));
    }
    ...
}

This example opens an XML document specified by a URL using the System.IO.Path, File, and FileStream classes. A new instance of DomXmlReader is created with the schema loader object m_schemaLoader. Then DomXmlReader.Read() reads the data in that file stream and creates a tree of DomNode instances from the XML data in that file. The DomNodes' data and their arrangement in that tree is the same as in the tree from which DomXmlWriter created the XML data. In other words, the data and its relationships in the tree are exactly the same as before. Read() returns a new instance of DomNode, which is the root node of the new DomNode tree.

The second part of this if statement is used when the requested file does not yet exist; the Open() method doubles as the way to create a new document. This part simply creates a new root DomNode of the root's type for an empty DomNode tree.

Note that after you read an XML file, there are usually other steps you need to take to initialize the DOM data so that it performs properly as a document. For example, you need to create a document, create viewable and/or editable contexts for the DOM data, and to initialize the DOM adapters for data types with the Is<T>(), As<T>(), or Cast<T>() methods. Your new document and contexts may use controls and adapters that need to be added and initialized. You may need to call the DomNode.InitializeExtensions() method to ensure that all the other DOM adapters, such as DOM validators, have been initialized.

For simplicity, some code was omitted from the previous example, but you can view it in entirety in the ATF Fsm Editor Sample or other ATF samples.

Persisting Data Without XML

If you have not used an XML Schema to define your data model or don't want to use XML as the persistence format for your DomNode trees, you need to create your own reader and writer classes. You can use DomXmlReader and DomXmlWriter as starting points for your own persistence methods. The ATF Simple DOM No XML Editor Sample provides an example of an application that uses the DOM, but does not use XML for its data model or for its persistence format. The Read() and Write() methods in its EventSequenceDocument class read and write persistent data in a simple format. For details, see this sample's code and read Persisting Data in the Simple DOM No XML Editor Programming Discussion.

Topics in this section

Clone this wiki locally