在C#中序列化 - 使用自己的格式?

时间:2012-03-28 15:41:50

标签: c# xml serialization format

我正在寻找将我的类转换为XML的方法,然后再转发。

即使使用Serialize也可以,但不幸的是我需要一个完全不同的问题。

不幸的是,我确实有时会在序列化程序周围找到一些东西来转换某些东西,但遗憾的是,它似乎没有办法实现这个目标。

所以我认为必须能够读取所有变量,但不需要手动输入硬编码。也许这里有人给我一个提示。

这是对其中一个类的简短测试:

public class C_20 //GENERAL DATA
{
    public string OBJAP = "test";
    public string AKTYP = "1";
    public string RLTP1 = "2";
    public string ROLE1 = "3";
}

我需要这种格式化的XML:

<ENTITY name="C_20">
    <ATTRIBUTES>
        <ATTRIBUTE name="OBJAP">test</ATTRIBUTE>
        <ATTRIBUTE name="AKTYP">1</ATTRIBUTE>
        <ATTRIBUTE name="RLTP1">2</ATTRIBUTE>
        <ATTRIBUTE name="ROLE1">3</ATTRIBUTE>
    </ATTRIBUTES>
</ENTITY>

我希望我可以帮助那些不得不用手写几千行的人,这显然很容易出错。

2 个答案:

答案 0 :(得分:4)

根据您的条件,我会在IXmlSerializable上实施C_20。关于如何创建您正在寻找的XML,这里有很好的阅读。

Proper way to implement IXmlSerializable?

答案 1 :(得分:2)

听起来我想将对象实例传递给序列化程序,并让该序列化程序自动枚举实例上的所有属性,并将它们作为XML字符串返回。

好消息:有几种方法可以做到这一点。您可能想要查看System.Reflection命名空间,它包含各种类型以帮助您在运行时检查对象。

作为一个简单的,强力的例子:

public string GetXml<T>(T instance)
{
    var type = typeof(T);
    var properties = type.GetProperties();
    var builder = new System.Text.StringBuilder();

    builder.AppendFormat("<{0}>", type.Name);

    foreach (var property in properties)
    {
        var name = property.Name;
        var value = property.InvokeMember(name, 
                                          BindingFlags.DeclaredOnly |         
                                          BindingFlags.Public |
                                          BindingFlags.NonPublic |
                                          BindingFlags.Instance |
                                          BindingFlags.GetProperty,
                                          null,
                                          instance,
                                          null);
        builder.AppendFormat("<{0}>{1}</{0}>", 
                             name,
                             value);          
    }

    builder.AppendFormat("</{0}>", type.Name);

    return builder.ToString();
}

这至少应该指向正确的方向。

编辑L.B

相同的想法,使用Linq2Xml

public static string GetXml<T>(T obj)
{
    Type t = typeof(T);
    XElement xElem = new XElement("ENTITY");
    xElem.Add(t.Name,
              new XElement("ATTRIBUTES",
                           t.GetFields()
                            .Select(f => new XElement("ATTRIBUTE", 
                                                      new XAttribute("name",f.Name), 
                                                      f.GetValue(obj)))
                            .ToArray())
    );

    return xElem.ToString();
}