XML to C# Class Question

2020-02-10 06:50发布

Can someone please help me, I have this xml snippet

<?xml version="1.0" encoding="utf-8" ?>
<EmailConfiguration>
  <DataBoxID>123</DataBoxID>
  <DefaultSendToAddressCollection>
     <EmailAddress>email@whereEver.com</EmailAddress>
  </DefaultSendToAddressCollection>
</EmailConfiguration>

I want to create a corressponding c# class from this. Before you say - "Just use xsd.exe", the output from Xsd cannot be serialized and deserialized correct, because it generates the class using partial classes.

Please can you tell me how to create this class.... here is the approach I took, but it doesn't work.

public class EmailConfiguration
{
    private string dataBoxID;

    public string DataBoxID
    {
        get { return dataBoxID; }
        set { dataBoxID = value; }
    }

    private DefaultSendToAddressCollectionClass defaultSendToAddressCollection;

    public DefaultSendToAddressCollectionClass DefaultSendToAddressCollection
    {
        get { return defaultSendToAddressCollection; }
        set { defaultSendToAddressCollection = value; }
    }
}

And here is the class declaration for the subclass

public class DefaultSendToAddressCollectionClass
{
    private string[] emailAddress;
    public string[] EmailAddress
    {
        get { return emailAddress; }
        set { emailAddress = value; }
    } 
}

标签: c# xml class
7条回答
疯言疯语
2楼-- · 2020-02-10 07:01

Did you use VS2008's XSD?

Here's the output I got:

c:>xsd email.xml
Writing file 'c:\email.xsd'

c:>xsd email.xsd /c /edb
Writing file 'c:\email.cs'

Generates serializable output:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class EmailConfiguration : object,  System.ComponentModel.INotifyPropertyChanged {

private string dataBoxIDField;

private EmailConfigurationDefaultSendToAddressCollection[] defaultSendToAddressCollectionField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string DataBoxID {
    get {
        return this.dataBoxIDField;
    }
    set {
        this.dataBoxIDField = value;
        this.RaisePropertyChanged("DataBoxID");
    }
}
查看更多
ゆ 、 Hurt°
3楼-- · 2020-02-10 07:06

Bare minimum working... looks like you are only required to add one attribute.

public class EmailConfiguration
{
    public string DataBoxID { get; set; }
    public DefaultSendToAddressCollectionClass DefaultSendToAddressCollection { get; set; }
}

public class DefaultSendToAddressCollectionClass
{
    [XmlElement]
    public string[] EmailAddress { get; set; }
}
查看更多
趁早两清
4楼-- · 2020-02-10 07:13

XSD.EXE is the tool that produces classes specifically for the purpose of XML Serialization. If it produces partial classes, that's because they work for XML Serialization. That's not what your problem is.

Try using XSD.EXE and serializing / deserializing. If you get an exception again, then please catch it and then post the results of ex.ToString().

查看更多
在下西门庆
5楼-- · 2020-02-10 07:14

You have two possibilities.

Method 1. XSD tool


Suppose that you have your XML file in this location C:\path\to\xml\file.xml

  1. Open Developer Command Prompt
    You can find it in Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools Or if you have Windows 8 can just start typing Developer Command Prompt in Start screen
  2. Change location to your XML file directory by typing cd /D "C:\path\to\xml"
  3. Create XSD file from your xml file by typing xsd file.xml
  4. Create C# classes by typing xsd /c file.xsd

And that's it! You have generated C# classes from xml file in C:\path\to\xml\file.cs

Method 2 - Paste special


Required Visual Studio 2012+

  1. Copy content of your XML file to clipboard
  2. Add to your solution new, empty class file (Shift+Alt+C)
  3. Open that file and in menu click Edit > Paste special > Paste XML As Classes
    enter image description here

And that's it!

Usage


Usage is very simple with this helper class:

using System;
using System.IO;
using System.Web.Script.Serialization; // Add reference: System.Web.Extensions
using System.Xml;
using System.Xml.Serialization;

namespace Helpers
{
    internal static class ParseHelpers
    {
        private static JavaScriptSerializer json;
        private static JavaScriptSerializer JSON { get { return json ?? (json = new JavaScriptSerializer()); } }

        public static Stream ToStream(this string @this)
        {
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(@this);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }


        public static T ParseXML<T>(this string @this) where T : class
        {
            var reader = XmlReader.Create(@this.Trim().ToStream(), new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
            return new XmlSerializer(typeof(T)).Deserialize(reader) as T;
        }

        public static T ParseJSON<T>(this string @this) where T : class
        {
            return JSON.Deserialize<T>(@this.Trim());
        }
    }
}

All you have to do now, is:

    public class JSONRoot
    {
        public catalog catalog { get; set; }
    }
    // ...

    string xml = File.ReadAllText(@"D:\file.xml");
    var catalog1 = xml.ParseXML<catalog>();

    string json = File.ReadAllText(@"D:\file.json");
    var catalog2 = json.ParseJSON<JSONRoot>();

Here you have some Online XML <--> JSON Converters: Click

查看更多
我欲成王,谁敢阻挡
6楼-- · 2020-02-10 07:16

Using .NET 3.5:

[XmlRoot]
public class EmailConfiguration
{
    [XmlElement]
    public string DataBoxID { get; set; }

    [XmlElement]
    public DefaultSendToAddressCollectionClass DefaultSendToAddressCollection { get; set; }
}

public class DefaultSendToAddressCollectionClass
{
    [XmlElement]
    public string[] EmailAddress { get; set; }
}
查看更多
Deceive 欺骗
7楼-- · 2020-02-10 07:17

This class will serialize the way you want. I changed your custom collection to a List and used the XmlArrayItem attribute to specify how each email address would be serialized. There are many such attributes to help you fine tune the serialization process.

[Serializable]
public class EmailConfiguration {
    private string dataBoxID;
    public string DataBoxID {
        get { return dataBoxID; }
        set { dataBoxID = value; }
    }

    private List<string> defaultSendToAddressCollection;

    [XmlArrayItem("EmailAddress")]
    public List<string> DefaultSendToAddressCollection {
        get { return defaultSendToAddressCollection; }
        set { defaultSendToAddressCollection = value; }
    }

    public EmailConfiguration() {
        DefaultSendToAddressCollection = new List<string>();
    }
}
查看更多
登录 后发表回答