使用C#XML Serializer生成自定义XML格式

时间:2015-04-14 09:50:11

标签: c# xml serializer

我正在使用Visual Studio 2013并尝试使用C#XML序列化器/反序列化器将存储在类中的变量转换为XML文件或从XML文件转换(我是新手)。

给出一个简单的类:

public class TestXML
{
    public String Label = "Hello";
    public Boolean Enable = true;
    public Int32 PosX = 12;
    public Int32 PosY = 34;
}

默认情况下,序列化程序以以下形式生成XML:

<TestXML>
  <Label>Hello</Label>
  <Enable>true</Enable>
  <PosX>12</PosX>
  <PosY>34</PosY>
</TestXML>

不幸的是,我的项目要求声明XML文件中的参数必须格式化为:

<TestXML>
  <model>
    <prop name="Label" value="Hello" />
    <prop name="Enable" value="true" />
    <prop name="PosX" value="12" />
    <prop name="PosY" value="34" />
  </model>
</TestXML>

我一直在考虑使用XmlAttributeXmlElement选项来控制XML格式,但无法查看生成所需格式的方法。有没有办法让序列化程序以这种特定的格式存储变量?

4 个答案:

答案 0 :(得分:3)

每个king.code手动控制序列化的答案是一个选项(所以我不再重复)。另一种选择是以不同方式构建模型,或者如果不是选项,则创建另一个“数据模型”并将现有模型映射到此并将其序列化。这可能比许多低级XmlReader / XmlWriter代码更容易。

要获得你想要的结果,你需要这样的东西:

public class TestXml
{
    [XmlArray("model")]
    [XmlArrayItem("prop")]
    public List<Prop> Props { get; set; }
}


public class Prop
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlAttribute("value")]
    public string Value { get; set; }
}

此内容:

var xml = new TestXml
{
    Props = new List<Prop>
    {
        new Prop
        {
            Name = "Label",
            Value = "Hello"
        }
    }
};

然后序列化为:

<TestXML>
  <model>
    <prop name="Label" value="Hello" />
  </model>
</TestXML>

答案 1 :(得分:1)

使用XmlAttributeAttribute无法做到这一点。您最好实现IXmlSerializable接口。

public class TestXML : IXmlSerializable
{
    public String Label = "Hello";
    public Boolean Enable = true;
    public Int32 PosX = 12;
    public Int32 PosY = 34;

    public void WriteXml(XmlWriter writer)
    {
        // Serialize
    }

    public void ReadXml(XmlReader reader)
    {
        // Deserialize
    }

    public XmlSchema GetSchema()
    {
        return null;
    }
}

通过这种方式,您可以完全控制XML的形状。您可以找到序列化/反序列化班级here所需的所有信息。

答案 2 :(得分:0)

您可以创建三个类

public class TextXML
{
 public Model model {get; set;}
}
public class Model
{      
 public List<prop> props{get; set;}
}
public class prop
{
public string name{get; set;}
public string value{get; set;}

}

并使用XmlAttributes对其进行序列化。将XmlArray用于模型类中的prop类。

如果您有任何其他问题不要害羞,我目前正在开发一个使用大量xml和属性的项目。

答案 3 :(得分:0)

这只能通过实现IXmlSerializable接口来完成,该接口允许您自定义XML的形状。

public class TestXML : IXmlSerializable
{
    public String Label = "Hello";
    public Boolean Enable = true;
    public Int32 PosX = 12;
    public Int32 PosY = 34;

    XmlSchema IXmlSerializable.GetSchema()
    {
        return null;
    }

    void IXmlSerializable.ReadXml(XmlReader reader)
    {
        reader.ReadStartElement();
        reader.ReadStartElement("model");

        if (reader.Name != "prop")
        { throw new InvalidOperationException(); }

        do
        {
            if (!reader.MoveToAttribute("name"))
            { throw new InvalidOperationException(); }

            string name = reader.Value;

            if (!reader.MoveToAttribute("value"))
            { throw new InvalidOperationException(); }

            switch (name)
            {
                case "Label": Label = reader.Value; break;
                case "Enable": Enable = XmlConvert.ToBoolean(reader.Value); break;
                case "PosX": PosX = XmlConvert.ToInt32(reader.Value); break;
                case "PosY": PosY = XmlConvert.ToInt32(reader.Value); break;
            }
        }
        while (reader.ReadToNextSibling("prop"));

        reader.ReadEndElement();
        reader.ReadEndElement();
    }

    void IXmlSerializable.WriteXml(XmlWriter writer)
    {
        writer.WriteStartElement("model");
        WriteProperty(writer, "Label", Label);
        WriteProperty(writer, "Enable", XmlConvert.ToString(Enable));
        WriteProperty(writer, "PosX", XmlConvert.ToString(PosX));
        WriteProperty(writer, "PosY", XmlConvert.ToString(PosY));
        writer.WriteEndElement();
    }

    private void WriteProperty(XmlWriter writer, string name, string value)
    {
        writer.WriteStartElement("prop");
        writer.WriteAttributeString("name", name);
        writer.WriteAttributeString("value", value);
        writer.WriteEndElement();
    }
}

<强>链接:

  1. IXmlSerializable Interface
  2. How to Implement IXmlSerializable Correctly