0

Hey Everyone have a question here about parsing some XML in C# .net 4 MVC 3.

I have a Map (HashMap) that is serialized to XML from a java app.

I need to parse this into an object on the dotnet side but can't seem to figure it out. In my research I see you can't serialize into Dictionary<string, string>.

Someone else suggested a public struct KeyValuePair<K, V> but that didn't seem to work.

Also tried an [XmlArray("mapConfig")]

One of the prerequisites is we have to use System.Xml.Serialization because we have an abstract messenger class and I would like to avoid changing that if I don't absolutely have to.

If I have to I could possiblly change the Java object if that would make this easier but would rather use the one already there if possible. If it helps the Java layer is using Xstream.

Here is a chunk of XML that is being sent from Java

<ConfigurationMap>
    <mapConfig class="hashtable">
      <entry>
        <string>Key1</string>
        <string>Value1</string>
      </entry>
      <entry>
        <string>Key2</string>
        <string>Value2</string>
      </entry>
      <entry>
        <string>Key3</string>
        <string>Value3</string>
      </entry>
      <entry>
        <string>Key4</string>
        <string>Value4</string>
      </entry>
    </mapConfig>
</ConfigurationMap>

Thanks, please let me know if you need more information. Look forward to the answers.

--UPDATE--

I thought it was apparent but I should've mentioned that the XML is coming back in the abstract message I mentioned in the form of a string. The current method uses:

XmlDocument doc = new XmlDocument();
doc.LoadXml(this.ResponseXml);
XmlElement main = doc.DocumentElement;

XmlElement cse = util.getElementsFirstChild(main, "MessagePayload");
XmlElement ccs = util.getElementsFirstChild(cse, "ReturnedObjectNameHERE");

We then deserialize the fragment using the System.Xml attributes on the model.

Here is a simple example of a Model we use with some generic properties :

[XmlRoot("list")]
public class SearchResults : List<CSearchResult>
{
    public SearchResults() { }
}

[XmlRoot("SearchResult")]
public class SearchResult
{
    [XmlElement("Id")]
    public string OrgUnitId { get; set; }

    [XmlElement("Type")]
    public Type Type { get; set; }

    [XmlElement("Name")]
    public string Name { get; set; }

    [XmlElement("Description")]
    public string Description { get; set; }
}

-- UPDATE 2 -- I was able to get some decent model binding using this model class below

[XmlRoot("ConfigurationMap")]
public class ConfigurationMap
{
    [XmlElement("mapConfig")]
    public MapConfig mapConfig { get; set; }

}

[XmlRoot("mapConfig")]
public class MapConfig
{
    [XmlArray("entry")]
    public List<string> entry { get; set; }
}

Only problem with this is the Object property mapconfig just bunches all of the entries together in one list, which makes sense given the model.

Trying to mess around with the array types to see if I can get a better result. Looking at making MapConfig an array of Entry. The I can either keep Entry a list or make Entry an array to so the object structure becomes:

MapConfig: [[key1, value1], [key2, value2], [key3, value3], [key4, value4],]

Trying to decide if this is a better structure to work with or not.

Any advice on this would be helpful as I work through this.

Thanks

9
  • 3
    This simple structure you could easily parse manually using XmlReader. Commented Mar 6, 2013 at 17:24
  • XmlReader Class; Commented Mar 6, 2013 at 17:28
  • This seems like homework, so I adjusted the tags as the OP says, "we have to use" Removed the tag java, as there is nothing in the question that relates to programming in java. Commented Mar 6, 2013 at 18:46
  • 3
    @ChuckSavage The homework tag is deprecated and shouldn't be used anymore. Consider questions on their merit, not on their motivation. Commented Mar 6, 2013 at 20:47
  • 1
    Also, your requirement is likely to make things more difficult than not. Java's XML serialisation and .NET's XML serialisation were not meant to interoperate or to conveniently handle mapping data structures to/from arbitrary XML, it seems counterproductive to try to force them to instead of using the right tool for the job. Commented Mar 6, 2013 at 20:49

2 Answers 2

2

You could create a class to serialize into... So run xsd.exe on the xml...

C:\>xsd test.xml
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 4.0.30319.17929]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\test.xsd'.

C:\>xsd test.xsd /classes
Microsoft (R) Xml Schemas/DataTypes support utility
[Microsoft (R) .NET Framework, Version 4.0.30319.17929]
Copyright (C) Microsoft Corporation. All rights reserved.
Writing file 'C:\test.cs'.

then just use the simple c# XmlSerializer...

NewClassName object = xml.DeSerializeStringToObject<NewClassName>();

Helper Class below

public static class XmlSerializerHelper
{
    public static T DeSerializeStringToObject<T>(this string sxml)
    {
        using (XmlTextReader xreader = new XmlTextReader(new StringReader(sxml.Replace("&", "&amp;"))))
        {
            XmlSerializer xs = new XmlSerializer(typeof(T));
            return (T)xs.Deserialize(xreader);
        }
    }

    public static string SerializeObjectToString(this object obj)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            XmlSerializer x = new XmlSerializer(obj.GetType());
            x.Serialize(stream, obj);
            return Encoding.Default.GetString(stream.ToArray());
        }
    }
}

Of course the the first string in the array will be the key.

Sign up to request clarification or add additional context in comments.

2 Comments

+1 for actually providing a constructive answer. Thank you. I am looking into this and trying out different ways to deserialize this. Unfortunately it doesn't look like there is a good built in attribute and model structure to account for this from what I have read. Outside of creating a custom dictionary serialization object.
So I was messing around with xsd for awhile yesterday and it kept creating classes that were unserializable with the given xml. Snooped around a bit and found out there is a bug in xsd when it tries to create and array of arrays from XML. You can see it here. This has given me some leads on some different types of model binding to try. Here is a link to the bug: stackoverflow.com/questions/2188930/…
0

The solution seemed to be simpler than I imagined but really was depended upon selecting the right combination of model attributes to parse correctly.

Here is the one I decided to use as it divides each entry up into its own list item.

[XmlRoot("ConfigurationMap")]
public class ConfigurationMap
{
    [XmlArray("mapConfig")]
    [XmlArrayItem("entry")]
    public List<Entry> MapConfig { get; set; }

}

[XmlRoot("entry")]
public class Entry
{
    [XmlElement("string")]
    public List<string> entry { get; set; }
}

Hopefully this helps out someone else. Thanks for the input everyone.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.