【问题标题】:Parse Java Map<string, string> from XML into C# Object将 Java Map<string, string> 从 XML 解析为 C# 对象
【发布时间】:2013-03-06 17:21:22
【问题描述】:

大家好,这里有一个关于在 C# .net 4 MVC 3 中解析一些 XML 的问题。

我有一个从 java 应用程序序列化为 XML 的 Map (HashMap)。

我需要将其解析为 dotnet 端的对象,但似乎无法弄清楚。在我的研究中,我发现您无法序列化为Dictionary&lt;string, string&gt;。

其他人建议使用public struct KeyValuePair&lt;K, V&gt;,但这似乎不起作用。

还尝试了[XmlArray("mapConfig")]

先决条件之一是我们必须使用System.Xml.Serialization,因为我们有一个抽象的信使类,如果我不是绝对必要的话,我想避免更改它。

如果必须的话,我可能会更改 Java 对象,如果这样做会更容易,但如果可能的话,我宁愿使用已经存在的对象。如果对 Java 层使用 Xstream 有帮助的话。

这是从 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>

谢谢,如果您需要更多信息,请告诉我。期待答案。

--更新--

我认为这很明显,但我应该提到 XML 将以字符串的形式返回到我提到的抽象消息中。当前方法使用:

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

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

然后我们使用模型上的System.Xml 属性反序列化片段。

这是一个简单的模型示例,我们使用一些通用属性:

[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; }
}

-- 更新 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; }
}

唯一的问题是 Object 属性 mapconfig 只是将所有条目聚集在一个列表中,考虑到模型,这很有意义。

尝试弄乱数组类型,看看能否得到更好的结果。看着使MapConfig 成为Entry 的数组。我可以将Entry 保留为列表或将Entry 设为数组,以便对象结构变为:

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

试图确定这是否是一个更好的结构。

在我解决这个问题时,任何关于这方面的建议都会有所帮助。

谢谢

【问题讨论】:

  • 这个简单的结构,您可以使用 XmlReader 轻松地手动解析。
  • 这似乎是家庭作业,所以我按照 OP 的说法调整了标签,"we have to use" 删除了标签 java,因为问题中没有与 java 编程相关的内容。
  • @ChuckSavage homework 标签已弃用,不应再使用。考虑他们的优点,而不是他们的动机。
  • 另外,您的要求可能会使事情变得更加困难。 Java 的 XML 序列化和 .NET 的 XML 序列化并不是为了互操作或方便地处理与任意 XML 之间的映射数据结构,试图强迫它们而不是使用正确的工具来完成这项工作似乎适得其反。

标签: c# java .net xml xml-serialization


【解决方案1】:

你可以创建一个类来序列化... 所以在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'.

然后只需使用简单的 c# XmlSerializer...

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

下面的助手类

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());
        }
    }
}

当然,数组中的第一个字符串是键。

【讨论】:

  • +1 用于实际提供建设性的答案。谢谢你。我正在研究这个并尝试不同的方法来反序列化它。不幸的是,从我所阅读的内容来看,似乎没有一个好的内置属性和模型结构来解释这一点。在创建自定义字典序列化对象之外。
  • 所以我昨天在 xsd 上搞砸了一段时间,它一直在创建无法使用给定 xml 序列化的类。窥探了一下,发现 xsd 在尝试从 XML 创建数组数组时存在错误。你可以在这里看到它。这给了我一些关于尝试一些不同类型的模型绑定的线索。以下是该错误的链接:stackoverflow.com/questions/2188930/…
【解决方案2】:

解决方案似乎比我想象的要简单,但实际上取决于选择正确的模型属性组合来正确解析。

这是我决定使用的,因为它将每个条目分成自己的列表项。

[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; }
}

希望这对其他人有所帮助。谢谢大家的意见。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 2020-03-17
    相关资源
    最近更新 更多