简体   繁体   English

解析Java地图 <string, string> 从XML到C#Object

[英]Parse Java Map<string, string> from XML into C# Object

Hey Everyone have a question here about parsing some XML in C# .net 4 MVC 3. 嘿,每个人都有一个关于在C#.net 4 MVC 3中解析一些XML的问题。

I have a Map (HashMap) that is serialized to XML from a java app. 我有一个从Java应用程序序列化为XML的Map(HashMap)。

I need to parse this into an object on the dotnet side but can't seem to figure it out. 我需要将它解析为dotnet端的一个对象,但似乎无法弄明白。 In my research I see you can't serialize into Dictionary<string, string> . 在我的研究中,我看到你无法序列化为Dictionary<string, string>

Someone else suggested a public struct KeyValuePair<K, V> but that didn't seem to work. 其他人建议使用public struct KeyValuePair<K, V>但这似乎不起作用。

Also tried an [XmlArray("mapConfig")] 还尝试了[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. 其中一个先决条件是我们必须使用System.Xml.Serialization因为我们有一个抽象的messenger类,如果我不是必须的话,我想避免改变它。

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. 如果必须的话,我可能会更改Java对象,如果这样可以使这更容易,但如果可能的话,宁可使用已存在的那个。 If it helps the Java layer is using Xstream. 如果它有助于Java层使用Xstream。

Here is a chunk of XML that is being sent from Java 这是从Java发送的一大块XML

<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-- --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. 我认为这很明显,但我应该提到XML是以字符串形式提到的抽象消息中回来的。 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. 然后,我们使用模型上的System.Xml属性对片段进行反序列化。

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 - 更新2 -我能够使用下面的这个模型类获得一些不错的模型绑定

[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. 唯一的问题是Object属性mapconfig只是将所有条目聚集在一个列表中,这对于模型是有意义的。

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 . 看看MapConfig是一个Entry数组。 The I can either keep Entry a list or make Entry an array to so the object structure becomes: 我可以保持Entry列表或使Entry成为一个数组,以便对象结构变为:

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 谢谢

You could create a class to serialize into... So run xsd.exe on the xml... 你可以创建一个序列化的类...所以在xml上运行xsd.exe ...

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... 那么只需使用简单的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. 当然,数组中的第一个字符串将是键。

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. 感谢大家的意见和建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM