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

标签 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;
    

将被序列化为:

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

但我也想保持第一个示例中的结构。

非常感谢。

最佳答案

您可以借助 XML 序列化器和反序列化器来实现此目的

类结构:

[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 { }
        }

反序列化:

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
        {

        }


    }

XML 文件将如下所示:

<?xml version="1.0" encoding="utf-8"?>
<A Name="">
  <B Name="">
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
  </B>
  <B Name="">
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
  </B>
  <B Name="">
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
    <C Name="">
      <B Name="" />
      <B Name="" />
      <B Name="" />
    </C>
  </B>
</A>

这能解决您的问题吗?

关于c# - 使用什么序列化程序(到 xml)进行循环引用和自定义字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44520269/

相关文章:

php - 如何使用 php 访问来自 url 的 xml 输出中的数据点?

c++ - 如何禁止分配给不引用变量?

c++ - 基于签名的 C++ 搜索

c# - 在给定类更改的情况下,在序列化之间键入对象

c# - 解码 JSON Web token (Xamarin.Android)

c# - Tuple<List<int>, List<int>> 还是 List<Tuple<int, int>>?

sql - 从 Android 访问 SQL 数据库?

c# - 从数据表创建列表到列表

java - 魔法 00 :09 timezone with DatatypeFactory

引用、对象和指针之间的 C++ 区别