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: