Имена пользовательских узлов с сериализацией XML (.NET) - PullRequest
3 голосов
/ 11 июля 2009

У меня есть следующий код:

public class Foo {}

static class Program {
    [XmlElement("foo")] // Ignored :(
    static public List<Foo> MyFoos { get; private set; }

    public static void Main() {
        MyFoos.Add(new Foo());
        MyFoos.Add(new Foo());

        XmlSerializer configSerializer = 
            new XmlSerializer(typeof(List<Foo>), new XmlRootAttribute("foos"));
        using (TextWriter w = new StreamWriter("test.xml"))
        {
            s.Serialize(w, MyFoos);
        }
    }
}

, который производит следующий XML-файл:

<?xml version="1.0" encoding="utf-8"?>
<foos xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Foo />
  <Foo />
</foos>

Что бы мне действительно хотелось, это элементы Foo, помеченные как foo, вместо этого ... Я понимаю, что это в основном косметическое средство, но оно соответствует тому, что обычно считается нормальным в XML.

1 Ответ

11 голосов
/ 11 июля 2009

Должно сработать, если указать имя элемента напрямую ...

   [XmlElement( ElementName = "foo" )]

См. Пример здесь . Дело в том, что оно должно быть статичным? Если это так, то это бесполезно, но это работает нормально (добавлено в оба раза за комментарий) ...

namespace TestSerial
{
    public class Foo
    {
        public int Value
        {
            get;
            set;
        }
    }
    public class SerializeMe
    {
        private List<Foo> _foos = new List<Foo>();
        public SerializeMe()
        {
        }

        [XmlElement("foo")]
        public List<Foo> MyFoos { get { return _foos; } }

    }

    class Program
    {
        static void Main(string[] args)
        {
            var fs = new SerializeMe();
            fs.MyFoos.Add(new Foo() { Value = 1 });
            fs.MyFoos.Add(new Foo() { Value = 2 });

            var s = new XmlSerializer(typeof(SerializeMe), new XmlRootAttribute("foos"));
            using (var w = new StreamWriter(@"c:\temp\test.xml"))
            {
                s.Serialize(w, fs);
            }

            using (var r = new StreamReader(@"c:\temp\test.xml"))
            {
                var o = s.Deserialize(r);
                var fs2 = (SerializeMe)o;

                fs2.MyFoos.Select(f => f.Value).ToList().ForEach(Console.WriteLine);
            }

            Console.ReadLine();
        }
    }
}

РЕДАКТИРОВАТЬ: (Мэтью, OP)

Мое окончательное решение, которое я считаю уточнением вышеизложенного, было:

public class Foo {}

[XmlRoot("foos")]
public class FooList 
{
    public FooList() { Foos = new List<Foo>(); }
    [XmlElement("foo")]
    public List<Foo> Foos { get; set; }
}

static class Program 
{
    static private FooList _foos = new FooList();
    static public List<Foo> MyFoos { get { return _foos; } }

    public static void Main() 
    {
        MyFoos.Add(new Foo());
        MyFoos.Add(new Foo());

        XmlSerializer configSerializer = 
            new XmlSerializer(typeof(FooList));

        using (TextReader r = new StreamReader("test.xml"))
        {
            _foos = (FooList)configSerializer.Deserialize(r);
        }

        using (TextWriter w = new StreamWriter("test.xml"))
        {
            configSerializer.Serialize(w, _foos);
        }
    }
}
...