使用XML序列化自定义节点名称 (.NET)

5

I have the following code:

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个回答

13

如果直接设置元素名称,它应该可以正常工作...

   [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();
        }
    }
}

编辑:(Matthew,原帖作者)

我的最终解决方案,我认为是上述解决方案的改进:

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);
        }
    }
}

1
XmlElementAttribute不允许在类定义上使用:属性'XmlElement'在此声明类型上无效。它只在'property,indexer,field,param,return'声明中有效。 - Matthew Scharley
1
这是一个静态属性,将始终被忽略。 - John Saunders
啊!我猜你被玩具示例咬了吧。 - JP Alioto
有些东西我想避免...但是反序列化后它也能正常工作吗?(我稍微担心该属性没有setter,但我对此还不熟悉) - Matthew Scharley
我将编辑并添加我的最终解决方案,因为我认为它比这个更简洁,但它在很大程度上基于这个,所以应该被接受。 - Matthew Scharley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接