0

我如何序列化以下结构使用XmlSerializer

  1. 只有 1 个实例Product

  2. 只有 1 个实例Updates

  3. Updates可以包含多个Item

  4. Item可以包含多个Artifact

XML:

<Product>
    <Cycle Type = "x0446" />
    <Brand Type = "z773g" Include="All" />
    <Updates>
        <Item Name = "Foo">
            <Artifact Kind="6" Action="3" />
        </Item>
        <Item Name = "Bar">
            <Artifact Kind="6" Action="3" />
            <Artifact Kind="53" Action="3" />
        </Item>
    </Updates>
</Product>
4

4 回答 4

3

您可以在数组或列表属性上使用 [XmlElement] 属性,并且 XmlSerializer 足够聪明,可以了解这一点并将它们一个接一个地列出在您的 xml 中。

或者

对于更复杂的结构,您可以使用 Visual Studio XML-to-class 生成器: - 单击 Windows 中的开始菜单 - 单击“所有程序” - 找到 Microsoft Visual Studio 文件夹并单击它 - 单击 Visual Studio Tools 文件夹 - 单击开发人员命令提示符。 .. - 假设您的 xml 保存在 C:\test\Sample.xml - 键入“xsd C:\test\Sample.xml /out:C:\test”这应该会通知您创建了一个模式。- 键入“xsd C:\test\Sample.xsd /c /out:C:\test”,这应该会通知您为您创建了一个 .cs 类,将其复制到您的解决方案中,可能会更改命名空间(或使用 xsd 命令参数) - 创建的类可能命名奇怪并且更难使用,如果您有复杂的 XML 或模式,请使用此方法。- 您可以使用部分类扩展生成的代码(查找),不要'

--

以下是直接代码(未生成)的样子:

public class Product{
    [XmlElement]
    public Cycle Cycle {get;set;}

    [XmlElement]
    public Brand Brand {get;set;}

    [XmlElement]
    public Updates Updates {get;set;}
}

public class Updates{
    [XmlElement("Item")]
    public UpdateItem[] Items{get;set;}
}

public class UpdateItem{ 
    [XmlAttribute]
    public string Name{get;set;} // use [XmlAttribute] in Cycle, Brand and Artifact classes

    [XmlElement("Artifact")]
    public Artifact[] Artifact{get;set;} 
}
//.... etc

这是生成的代码的样子:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class ProductUpdatesItem {

private ProductUpdatesItemArtifact[] artifactField;

private string nameField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Artifact", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public ProductUpdatesItemArtifact[] Artifact {
    get {
        return this.artifactField;
    }
    set {
        this.artifactField = value;
    }
}

[/代码]

于 2012-12-03T17:33:45.120 回答
2

您可以使用属性控制 xml 序列化。使用XmlAttribute属性,将默认序列化作为元素更改为序列化作为属性。使用XmlElement属性将列表序列化为 xml 元素的平面序列。

public class Product
{
    public Cycle Cycle { get; set; }
    public Brand Brand { get; set; }
    public List<Item> Updates { get; set; }
}

public class Cycle
{
    [XmlAttribute("Type")]
    public string Type { get; set; }    
}

public class Brand
{
    [XmlAttribute("Type")]
    public string Type { get; set; }
    [XmlAttribute("Include")]
    public string Include { get; set; }
}

public class Item
{
    [XmlAttribute("Name")]
    public string Name { get; set; }
    [XmlElement("Artifact")]
    public List<Artifact> Artifacts { get; set; }
}

public class Artifact
{
    [XmlAttribute("Kind")]
    public int Kind { get; set; }
    [XmlAttribute("Action")]
    public int Action { get; set; }
}

序列化:

Product p = new Product()
{
    Cycle = new Cycle() { Type = "x0446" },
    Brand = new Brand() { Type = "z773g", Include = "All" },
    Updates = new List<Item>()
    {
        new Item() { Name = "Foo", 
                     Artifacts = new List<Artifact>() {
                        new Artifact() { Action = 3, Kind = 6 }
                    }
        },
        new Item() { Name = "Bar", 
                     Artifacts = new List<Artifact>() {
                        new Artifact() { Action = 3, Kind = 6 },
                        new Artifact() { Action = 3, Kind = 53 },
                    }
        }
    }
};

XmlSerializer serializer = new XmlSerializer(typeof(Product));
Stream stream = new MemoryStream(); // use whatever you need
serializer.Serialize(stream, p);

结果:

<Product>
    <Cycle Type = "x0446" />
    <Brand Type = "z773g" Include="All" />
    <Updates>
        <Item Name = "Foo">
            <Artifact Kind="6" Action="3" />
        </Item>
        <Item Name = "Bar">
            <Artifact Kind="6" Action="3" />
            <Artifact Kind="53" Action="3" />
        </Item>
    </Updates>
</Product>
于 2012-12-03T16:48:04.403 回答
0

如果您有此结构的 XML 模式(或可以生成一个) - 我的首选是使用 XSD.exe 来生成类。

于 2012-12-03T17:34:34.670 回答
0

这里有一些代码(错过了一个属性)

using System;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;

[Serializable]
[XmlRoot("Product")]
public class Product
{
    [XmlElement("Cycle")]
    public Cycle Cycle { get; set; }

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

    public Product()
    {
        Cycle = new Cycle();
        Updates = new Updates();
    }
}

[Serializable]
public class Cycle
{
    [XmlAttribute("Type")]
    public string Type { get; set; }
}

[Serializable]
public class Updates
{
    [XmlElement("Item")]
    public List<Item> Items { get; set; }

    public Updates()
    {
        Items = new List<Item>();
    }
}

[Serializable]
public class Item
{
    [XmlElement("Artifact", typeof(Artifact))]
    public List<Artifact> Artifacts { get; set; }

    public Item()
    {
        Artifacts = new List<Artifact>();
    }
}

[Serializable]
public class Artifact
{
    [XmlAttribute("Kind")]
    public int Kind { get; set; }
}

这里是序列化的代码

using System;
using System.Xml;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.IO;
using System.Text;

    private static string SerializeMe(object o)
    {
        XmlSerializer s = new XmlSerializer(o.GetType());

        MemoryStream stream = new MemoryStream();

        XmlWriter writer = new XmlTextWriter(stream, Encoding.Default);

        s.Serialize(writer, o);

        stream.Flush();

        stream.Seek(0, SeekOrigin.Begin);

        return Encoding.Default.GetString(stream.ToArray());
    }

现在这里是控制台上的测试代码

    static void Main(string[] args)
    {
        Product p = new Product();

        p.Cycle.Type = "whatever";

        Item i = new Item();
        i.Artifacts.Add(new Artifact{Kind = 45});

        p.Updates.Items.Add(i);

        Console.WriteLine(SerializeMe(p));

        Console.ReadLine();
    }

希望这可以帮助 :)

于 2012-12-03T16:43:53.673 回答