【问题标题】:Custom node names with XML serialization (.NET)具有 XML 序列化 (.NET) 的自定义节点名称
【发布时间】:2009-07-11 02:36:27
【问题描述】:

我有以下代码:

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>

我真正想要的是标记为fooFoo 元素,而不是...我意识到这主要是装饰性的,但它符合XML 中通常认为的正常内容。

【问题讨论】:

    标签: .net xml xml-serialization


    【解决方案1】:

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

       [XmlElement( ElementName = "foo" )]
    

    参见示例here。它必须是静态的吗?如果是这样,这没有帮助,但这很好用(添加了每条评论的往返)...

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

    【讨论】:

    • XmlElementAttribute 不允许用于类定义:属性“XmlElement”在此声明类型上无效。它仅对“属性、索引器、字段、参数、返回”声明有效。
    • 这是一个静态属性,将永远被忽略。
    • 啊!我猜被玩具例子咬了。
    • 我想避免的事情......但是再次反序列化它是否也能正常工作? (我有点担心该物业缺少二传手,但我是新手)
    • 我要编辑这个并添加我的最终解决方案,因为我发现它比这个更干净,但它很大程度上基于这个,所以它应该被接受。
    猜你喜欢
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多