Save and load to xml using MemoryStream

5 posts, 1 answers
  1. Tung
    Tung avatar
    11 posts
    Member since:
    Jan 2017

    Posted 04 Apr Link to this post

    Hi

    I'm trying to save and load a RadDock layout to a database field using a MemoryStream but the code fails on loading the layout with error 'System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.'

    I have very similar code to save and load layouts for RadDock and it works. Also I can save and load dock layouts if I use xml files but I don't want to use them.

    I'm using Progress OpenEdge andthese are code snippets for saving and loading the layout.

    METHOD PRIVATE VOID SaveDockLayout( ):
        DEF VAR l_MemoryStream AS System.IO.MemoryStream   NO-UNDO.
        DEF VAR l_UTF8Encoding AS System.Text.UTF8Encoding NO-UNDO.
        DEF VAR lc_char        AS LONGCHAR                 NO-UNDO.

        ASSIGN
            l_MemoryStream = NEW System.IO.MemoryStream()
            l_UTF8Encoding = NEW System.Text.UTF8Encoding()
            .
        radDock1:SaveToXml(l_MemoryStream).
        lc_char = l_UTF8Encoding:GetString(l_MemoryStream:ToArray()).
        COPY-LOB FROM lc_char TO tt_stored_layout.layout.

        l_MemoryStream:Close().
        l_MemoryStream = ?.
        DELETE OBJECT l_MemoryStream NO-ERROR.
        DELETE OBJECT l_UTF8Encoding NO-ERROR.

    END METHOD.

    METHOD PRIVATE VOID LoadDockLayout( ):
        DEF VAR l_MemoryStream AS System.IO.MemoryStream   NO-UNDO.
        DEF VAR l_UTF8Encoding AS System.Text.UTF8Encoding NO-UNDO.
        DEF VAR lc_char        AS LONGCHAR                 NO-UNDO.

        COPY-LOB FROM tt_stored_layout.layout TO lc_char.

        ASSIGN
            l_UTF8Encoding = NEW System.Text.UTF8Encoding()
            l_MemoryStream = NEW System.IO.MemoryStream(l_UTF8Encoding:GetBytes(lc_char), 0, l_UTF8Encoding:GetByteCount(lc_char))
            .
        radDock1:SuspendLayout().
        radDock1:LoadFromXml(l_MemoryStream).
        radDock1:ResumeLayout().

        l_MemoryStream:Close().
        l_MemoryStream = ?.
        DELETE OBJECT l_MemoryStream NO-ERROR.
        DELETE OBJECT l_UTF8Encoding NO-ERROR.

    END METHOD.

    Can you help or give me an example of using a method to save and load dock layouts withouth resorting to xml files?

    Kind regards

    Tung

  2. Hristo
    Admin
    Hristo avatar
    1016 posts

    Posted 05 Apr Link to this post

    Hi Tung,

    Thank you for writing back.

    Can you please try removing your database related code and check if you would be able to restore the layout by reading a string in-memory string:  
    public partial class Form1 : Form
    {
        string res;
     
        public Form1()
        {
            InitializeComponent();
        }
     
        private void radButton1_Click(object sender, EventArgs e)
        {
            MemoryStream ms = new MemoryStream();
            this.radDock1.SaveToXml(ms);
            UTF8Encoding encoding = new UTF8Encoding();
            res = encoding.GetString(ms.ToArray());
     
            ms.Dispose();
        }
     
        private void radButton2_Click(object sender, EventArgs e)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            MemoryStream ms = new MemoryStream(encoding.GetBytes(res),0, encoding.GetByteCount(res));
            this.radDock1.LoadFromXml(ms);
            ms.Dispose();
        }
    }

    I hope this helps. Should you have further questions please do not hesitate to write back.

    Regards,
    Hristo
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Tung
    Tung avatar
    11 posts
    Member since:
    Jan 2017

    Posted 06 Apr in reply to Hristo Link to this post

    Hi Hristo

    That didn't work unfortunately, I get the same error.

    I tried the datatypes CHARACTER and LONGCHAR (same but not limited to 32KB in size), which are equivalent to System.String.

    This is the stack trace in case it helps.

    .NET StackTrace:
    -->   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
       at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
       at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
       at Telerik.WinControls.UI.Docking.RadDock.IsOldXmlFormat(XmlReader reader)
       at Telerik.WinControls.UI.Docking.RadDock.LoadFromXml(Stream stream)

    Regards

    Tung

  4. Answer
    Hristo
    Admin
    Hristo avatar
    1016 posts

    Posted 07 Apr Link to this post

    Hi Tung,

    Thank you for writing back.

    The error appears to be related to ABL and your stream object. Using the same code in a C# application does not result in an exception. The error is in the System.Xml.XmlReader class which fails in its Read method. You can check the following forum thread discussing a similar issue: http://stackoverflow.com/questions/17947238/why-data-at-the-root-level-is-invalid-line-1-position-1-for-xml-document.

    I hope this helps. Should you have further questions please do not hesitate to write back.

    Regards,
    Hristo
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Tung
    Tung avatar
    11 posts
    Member since:
    Jan 2017

    Posted 07 Apr Link to this post

    Hi Hristo

    I was able to adapt a solution from that linked discussion.

    My xml had a '?' at the start, i.e. ?<?xml version="1.0" encoding="utf-8"?>

    Thanks

    Tung

Back to Top