Zlex
Zlex

Reputation: 147

read line and keep spaces from xml file

I am trying to write in xml file some profiles that i created so far so good ,

the input string is ProfilesList(0) = "45 65 67" ProfilesList(1) = "profilename";

public void CreateGroupXML(String GroupNameWithPath, List<String> ProfilesList)
{
        ProfilesGroup.ProfilesList = ProfilesList;

        XmlWriterSettings ws = new XmlWriterSettings();
        ws.NewLineHandling = NewLineHandling.Entitize;
        for (int i = 0; i < ProfilesList.Count; i++)
        {
            ProfilesList[i] += Environment.NewLine;
        }


        XmlSerializer serializer = new XmlSerializer(typeof(ProfilesGroup));
        using (XmlWriter wr = XmlWriter.Create(GroupNameWithPath, ws))
        {
            serializer.Serialize(wr, ProfilesGroup);
        }

    }

}

in the xml file the profiles written like that :

ProfilesList="45 65 67&#xA; profilename&#xA;

So far so good, the problem happens when i trying read from the xml file it split the first profile name into 3 here the code

    public List<string> getProfilesOfGroup(string groupNameFullPath)
    {
        Stream stream = null;
        try
        {
            stream = File.OpenRead(groupNameFullPath);
            XmlSerializer serializer = new XmlSerializer(typeof(ProfilesGroup));
            _ProfilesGroup = (ProfilesGroup)serializer.Deserialize(stream);
            stream.Close();
            return _ProfilesGroup.ProfilesList;
        }
        catch (Exception Ex)
        {
            log.ErrorFormat("Exception in getProfilesOfGroup: {0}", Ex.Message);
            if (stream != null)
            {
                stream.Close();
            }
            return null;
        }
    }

the output (lets call the string ProfileList) contains :
ProfileList(0) = 45
ProfileList(1) = 65
ProfileList(2) = 67
ProfileList(3) = profilename

and i expecting the string to contain
ProfileList(0) = 45 65 67
ProfileList(1) = profilename

edit here the full xml :

?xml version="1.0" encoding="utf-8"?ProfilesGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ProfilesList="45 65 67 profilename "

and the class:

[XmlRootAttribute("VProfilesGroup", IsNullable = false, DataType = "", Namespace = "")]
public class ProfilesGroup
{
    [XmlAttribute("ProfilesList")]
    public List<String> ProfilesList = new List<string>();
}

Upvotes: 2

Views: 501

Answers (1)

dbc
dbc

Reputation: 116516

Why not just remove the [XmlAttribute("ProfilesList")] attribute? Your data will be serialized and deserialized successfully. The XML will look like:

<VProfilesGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ProfilesList>
        <string>45 65 67</string>
        <string>profilename</string>
    </ProfilesList>
</VProfilesGroup>

In this format the list of strings is clearly defined to have two entries. This is the standard way to serialize & deserialize an array of strings with XmlSerializer. Or do you have some external constraint making you declare the list as an attribute?

Update

If you must serialize the ProfilesList as an attribute not an array of elements, you can manually construct and deconstruct the string like so:

[XmlRootAttribute("VProfilesGroup", IsNullable = false, DataType = "", Namespace = "")]
public class ProfilesGroup
{
    static readonly char Delimiter = '\n';

    [XmlIgnore]
    public List<String> ProfilesList { get; set; } // Enhance the setter to throw an exception if any string contains the delimiter.

    [XmlAttribute("ProfilesList")]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public string ProfilesListText
    {
        get
        {
            return string.Join(Delimiter.ToString(), ProfilesList.ToArray());
        }
        set
        {
            ProfilesList = new List<string>(value.Split(Delimiter));
        }
    }

    public static string CreateGroupXML(List<String> ProfilesList)
    {
        var group = new ProfilesGroup();
        group.ProfilesList = ProfilesList;
        return XmlSerializationHelper.GetXml(group);
    }

    public static List<string> GetProfilesOfGroup(string xml)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(ProfilesGroup));
        var group = (ProfilesGroup)serializer.Deserialize(new StringReader(xml));
        return group == null ? null : group.ProfilesList;
    }

    public static void Test()
    {
        List<string> list = new List<string>(new string[] { "45 65 67", "profilename" });
        var xml = CreateGroupXML(list);
        var newList = GetProfilesOfGroup(xml);
        bool same = list.SequenceEqual(newList);
        Debug.Assert(same); // No assert.
    }
}

The resulting XML looks like:

<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<VProfilesGroup xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ProfilesList=\"45 65 67&#xA;profilename\" />

In this case, I am testing the code by serializing and deserializing to a string rather than to a file. And then the helper:

public static class XmlSerializationHelper
{
    public static string GetXml<T>(T obj, XmlSerializer serializer) where T : class
    {
        using (var textWriter = new StringWriter())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;        // For cosmetic purposes.
            settings.IndentChars = "    "; // The indentation used in the test string.
            using (var xmlWriter = XmlWriter.Create(textWriter, settings))
            {
                serializer.Serialize(xmlWriter, obj);
            }
            return textWriter.ToString();
        }
    }

    public static string GetXml<T>(T obj) where T : class
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        return GetXml(obj, serializer);
    }
}

Upvotes: 1

Related Questions