要使用什么序列化程序(到xml)进行循环引用和自定义字段?

时间:2017-06-13 11:29:24

标签: c# xml reference datacontract circular-reference

我有以下xml:

<A name="">
    <B name="">
        <C name="">
            <B name=""/>
            <B name=""/>
        </C>
    </B>
    <B name="">
        <C name="">
            <B name=""/>
            <B name=""/>
            <B name=""/>
            <B name=""/>
        </C>
    </B>
</A>

请注意元素C创建循环引用,因此我无法使用XmlSerializer。

我如何反序列化和序列化? 似乎我不能使用DataContractSerializer,因为:

  1. DataContract不支持属性(在我的示例中为“Name”)
  2. DataContract不支持忽略外部元素名称,例如

    List<B> BList;
    
  3. 将序列化为:

    <C name="">
        <BList>
            <B name=""/>
            <B name=""/>
        </Blist>
    </C>
    

    但是我也希望像第一个例子那样保持结构。

    非常感谢。

2 个答案:

答案 0 :(得分:1)

您可以借助XML Serializer和Deserializer

来实现这一目标

班级结构:

printf("\nSize of struct on_off = %d\n", (int)sizeof(struct on_off));
printf("\nSize of box_props = %d\n", (int)sizeof(struct box_props));

填充对象(根据您的要求更新):

[XmlRoot(ElementName = "A")]
    public class A
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }
        private List<B> b = new List<B>();

        [XmlElement("B")]
        public List<B> B
        {
            get { return b; }
            set { b = value; }
        }
    }

    public class B
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }
        private List<C> c = new List<C>();

        [XmlElement("C")]
        public List<C> C
        {
            get { return c; }
            set { c = value; }
        }
    }

    public class C
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }
        private List<B> b = new List<B>();

        [XmlElement("B")]
        public List<B> B
        {
            get { return b; }
            set { b = value; }
        }
    }

<强>序列化

private A a = new A();
        private void Load()
        {
            a.B.Clear();
            a.Name = string.Empty;
            for (int i = 0; i < 3; i++)
            {
                var tempB = new B();
                tempB.Name = string.Empty;
                for (int j = 0; j < 5; j++)
                {
                    var tempC = new C();
                    tempC.Name = string.Empty;
                    for (int k = 0; k < 3; k++)
                    {
                        var innerChildB = new B();
                        innerChildB.Name = string.Empty;
                        tempC.B.Add(innerChildB);
                    }
                    tempB.C.Add(tempC);
                }
                a.B.Add(tempB);
            }
        }

<强>反序列化

private void Serialize()
        {
            try
            {
                // to Save columnorders to the file
                var serializer = new XmlSerializer(typeof(A));
                var ns = new XmlSerializerNamespaces();
                ns.Add("", "");

                using (TextWriter writer = new StreamWriter(@"D:\Test_Jun13.xml"))
                {
                    serializer.Serialize(writer, a, ns);
                }
            }
            catch { }
        }

XML文件将如下所示:

private void DeSerialize()
    {
        try
        {
            if (File.Exists(@"D:\Test_Jun13.xml"))
            {
                var deserializer = new XmlSerializer(typeof(A));
                using (TextReader reader = new StreamReader(@"D:\Test_Jun13.xml"))
                {
                    var obj = deserializer.Deserialize(reader);
                    a = (A)obj;
                }
            }
        }
        catch
        {

        }


    }

这会解决您的问题吗?如果这有助于您,请不要忘记将其标记为答案

答案 1 :(得分:0)

如果您只关心序列化/反序列化,那么您应该使用支持循环的序列化器,例如Json.Net。如果我没有记错的话binary serializer应该也可以。