Сериализация в C # - с собственным форматом? - PullRequest
2 голосов
/ 28 марта 2012

Я ищу способ перевести мои классы в 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 ]

4 голосов
/ 28 марта 2012

Исходя из ваших критериев, я бы реализовал IXmlSerializable на C_20.Здесь вы найдете отличную статью о том, как создать XML, который вы ищете.

Правильный способ реализации IXmlSerializable?

2 голосов
/ 28 марта 2012

Мне кажется, что вы хотите передать экземпляр объекта сериализатору, и этот сериализатор автоматически перечисляет все свойства экземпляра и возвращает их в виде строки 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...