Working with the CDATA Section

The CDATA section is used to store any symbol data, which is not parsed on processing XML file. All the data located in the CDATA section is interpreted as characters, and not as markup or links to object. The CDATA section also enables the user to save a binary data stream.

Consider a small example that illustrates saving of the Document object contents to the CDATA section from repository and further loading the object from XML file.

NOTE. As on working the data is transformed to a character string, the specified example can be used to save or load only small objects.

Sub Save;
Var
    MB: IMetabase;
    ID_DOC: String = "REPO_IMG";
    Doc: IDocument;
    Stream: IIOStream;
    Bytes: Array Of Integer;
    Result: String;
    XMLDoc: IXMLDOMDocument;
    XMLName: String = "c:\Documents.xml";
    Root, Element: IXmlDomElement;
    CDATA: IXmlDomCDATASection;
    Loaded: Boolean;
    i: Integer;
Begin
    MB := MetabaseClass.Active;
    Doc := MB.ItemById(ID_DOC).Bind As IDocument;
    //View of document contents as a stream
    Stream := Doc.GetAsStream;
    //Get a list of bits as a string
    Stream.Seek(0, SeekOrigin.Beginning);
    Bytes := New Integer[Stream.Size];
    Debug.WriteLine("Size: " + Stream.Size.ToString);
    For i := 0 To Stream.Size - 1 Do
        Bytes[i] := Stream.ReadByte;
        Result := Result + Bytes[i].ToString + "|"//Bits are separated with the character - "|"
    End For;
    Result := Result.SubString(0, Result.Length - 1); //Remove the last insignificant "|"
    //Work with XML file
    XMLDoc := New DOMDocument60.Create;
    Loaded := XMLDoc.load(XMLName);
    //If file exists, open it, otherwise create it
    If Loaded Then
        Root := XMLDoc.documentElement;
    Else
        Root := XMLDoc.createElement("DOCUMENTS");
        XMLDoc.appendChild(Root);
    End If;
    //Create a new element and CDATA section
    Element := XMLDoc.createElement("DOCUMENT");
    CDATA := XMLDoc.createCDATASection(Result);
    /Save document identifier in the ID attribute
    Element.setAttribute("ID", ID_DOC);
    //The CDATA section as a child section for DOCUMENT
    Element.appendChild(CDATA);
    Root.appendChild(Element);
    //Save
    XMLDoc.save(XMLName);
End Sub Save;

On executing the Save method a document with the REPO_IMG identifier is saved to XML file. A new element is created for the document, identifier is saved to the ID element attribute, document contents is saved to the CDATA section.

Sub Load;
Var
    XMLDoc: IXMLDOMDocument;
    XMLName: String = "c:\Documents.xml";
    ID_DOC: String = "REPO_IMG";
    Root, Element: IXmlDomElement;
    CDATA: IXmlDomCDATASection;
    Loaded: Boolean;
    BytesString: Array Of String;
    Stream: IMemoryStream;
    i: Integer;
Begin
    //Load document
    XMLDoc := New DOMDocument60.Create;
    Loaded := XMLDoc.load(XMLName);
    If Loaded Then
        Root := XMLDoc.documentElement;
    Else
        Debug.WriteLine("File is missing");
        Return;
    End If;
    //Get the DOCUMENT document with set value of the ID attribute
    Element := Root.selectSingleNode("DOCUMENT[@ID=""" + ID_DOC + """]"As IXmlDomElement;
    If Element <> Null Then
        //Get CDATA
        CDATA := Element.firstChild As IXmlDomCDATASection;
        //Get a list of bits from CDATA
        BytesString := CDATA.data.Split("|");
        //A stream, to which bits are put
        Stream := New MemoryStream.Create;
        Stream.Seek(0, SeekOrigin.Beginning);
        //Read data from array to stream
        For i := 0 To BytesString.Length - 1 Do
            Stream.WriteByte(Integer.Parse(BytesString[i]));
        End For;
        Debug.WriteLine("Read example: " + Stream.Size.ToString);
        //...
        //Further work with the Stream stream
        //...
    Else
        Debug.WriteLine("Document with specified identifier is missing.");
        Return;
    End If;
End Sub Load;

On executing the Load method XML file is loaded. The DOCUMENT element with the set value of the ID attribute is searched in the file. If the element is found, data is read from its child CDATA section to the stream.

See also:

XML Assembly | Examples of Working with XML Files