【问题标题】:Deserializing XML to Objects in C#在 C# 中将 XML 反序列化为对象
【发布时间】:2010-09-18 14:27:43
【问题描述】:

所以我的 xml 看起来像这样:

<todo-list>
  <id type="integer">#{id}</id>
  <name>#{name}</name>
  <description>#{description}</description>
  <project-id type="integer">#{project_id}</project-id>
  <milestone-id type="integer">#{milestone_id}</milestone-id>
  <position type="integer">#{position}</position>

  <!-- if user can see private lists -->
  <private type="boolean">#{private}</private>

  <!-- if the account supports time tracking -->
  <tracked type="boolean">#{tracked}</tracked>

  <!-- if todo-items are included in the response -->
  <todo-items type="array">
    <todo-item>
      ...
    </todo-item>
    <todo-item>
      ...
    </todo-item>
    ...
  </todo-items>
</todo-list>

如何使用 .NET 的序列化库将其反序列化为 C# 对象?

目前我正在使用反射,并使用命名约定在 xml 和我的对象之间进行映射。

【问题讨论】:

    标签: c# .net serialization


    【解决方案1】:

    为每个元素创建一个类,为每个元素创建一个属性,为每个子元素创建一个对象列表或数组(使用创建的对象)。然后在字符串上调用 System.Xml.Serialization.XmlSerializer.Deserialize 并将结果转换为您的对象。使用 System.Xml.Serialization 属性进行调整,例如将元素映射到您的 ToDoList 类,使用 XmlElement("todo-list") 属性。

    快捷方式是将您的 XML 加载到 Visual Studio 中,单击“推断架构”按钮并运行“xsd.exe /c schema.xsd”以生成类。 xsd.exe 位于工具文件夹中。然后检查生成的代码并进行调整,例如在适当的地方将 short 更改为 int。

    【讨论】:

    • 在 VS2010 中,它被称为“创建架构”,可能会生成多个 xsd 文件(每个命名空间一个)。在这种情况下,将它们包含在命令中,即运行“xsd.exe /c schema.xsd schema1.xsd”(等)。
    • 在 VS 2012 及更高版本中,编辑菜单中还有“将 XML 粘贴为类”。
    • Edit &gt; Paste Special &gt; Paste XML as Classes 非常好,@JonathanAllen,正是我所需要的。
    【解决方案2】:

    归结为在 VS 中使用工具中的 xsd.exe:

    xsd.exe "%xsdFile%" /c /out:"%outDirectory%" /l:"%language%"
    

    然后用阅读器和反序列化器加载它:

    public GeneratedClassFromXSD GetObjectFromXML()
    {
        var settings = new XmlReaderSettings();
        var obj = new GeneratedClassFromXSD();
        var reader = XmlReader.Create(urlToService, settings);
        var serializer = new System.Xml.Serialization.XmlSerializer(typeof(GeneratedClassFromXSD));
        obj = (GeneratedClassFromXSD)serializer.Deserialize(reader);
    
        reader.Close();
        return obj;
    }
    

    【讨论】:

    • 嗯,在示例中我假设变量urlToService 表示序列化的XML?该变量应该是GetObjectFromXML() 的参数吗?
    • 对于未来的访问者:urlToService 可以是 xml 文件的路径。像魅力一样工作。
    【解决方案3】:

    反序列化任何对象,只要 T 类型被标记为 Serializable:

    function T Deserialize<T>(string serializedResults)
    {
        var serializer = new XmlSerializer(typeof(T));
        using (var stringReader = new StringReader(serializedResults))
            return (T)serializer.Deserialize(stringReader);
    }
    

    【讨论】:

    • 不是Deserialize&lt;T&gt;(string s),你是说Deserialize&lt;T&gt;(string serializedResults)吗?
    • 已修复。谢谢@DavidRR!
    【解决方案4】:

    好吧,您的程序集中必须有大致匹配 XML 的类(称为 Private 的属性、称为 ToDo 的集合属性等)。

    问题在于XML 中包含对类名无效的元素。因此,您必须在这些类中实现 IXmlSerializable 来控制它们如何与 XML 进行序列化。您也可以使用一些 xml 序列化特定属性来摆脱困境,但这取决于您的 xml 架构。

    这是使用反射的一个步骤,但它可能不是您所希望的。

    【讨论】:

      【解决方案5】:

      结帐http://xsd2code.codeplex.com/

      Xsd2Code 是来自 XSD 架构的 CSharp 或 Visual Basic 业务实体类生成器。

      【讨论】:

      • @Deepfreezed:请提供更多细节。这将如何解决这个问题中的问题。也许展示一个使用该工具的代码示例。
      • 首先我使用 VS 为 XML 生成了 XSD 架构。然后我运行上面的代码生成工具。这生成了一个类/对象,我可以使用它来序列化 XML。该工具与 VS 2008/2010 集成。它还具有一些不错的功能,例如通用集合。
      【解决方案6】:

      有几个不同的选项。

      • Visual Studio 包含一个名为 xsd.exe 的命令行程序。您使用该程序来创建模式文档,并在模式文档上再次使用该程序来创建可以与system.xml.serialization.xmlserializer 一起使用的类
      • 您也许可以在其上调用 Dataset.ReadXml()。

      【讨论】:

        【解决方案7】:

        几年前我有同样的问题,即如何将 xml 映射到 C# 类或创建映射到我们的 XML 的 C# 类,就像我们在实体框架中所做的一样(我们将表映射到 C# 类)。我最终创建了一个框架,它可以从您的 XML 中创建 C# 类,这些类可用于读取/写入您的 xml。有一个look

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-30
          • 1970-01-01
          • 2018-07-17
          • 2023-03-29
          • 1970-01-01
          • 2018-10-11
          • 1970-01-01
          相关资源
          最近更新 更多