C# 循环引用和自定义字段使用哪种序列化程序(到xml)?
我有以下xml:C# 循环引用和自定义字段使用哪种序列化程序(到xml)?,c#,xml,reference,datacontract,circular-reference,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=""/>
<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,因为:
List<B> BList;
列表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 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>
反序列化:
[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 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>
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 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
引用其包含对象B
,则这是一个循环引用。是这样吗?您展示的XML中没有循环引用,更具体地说,不可能用XML描述循环引用,您不能创建包含其父对象的子对象。@EmrahSüngüyes@Gusman我相信这样的结构可以代表逻辑树,当每个节点可以包含另一个节点时。在XML中,您可以描述不同的实例,但不能重用同一实例将其分配给其他项。例如,“A”中的“B”项与“C”中的“B”项不同,它们属于相同的类型,但具有不同的实例,因此没有循环引用,要创建循环引用,您需要使用相同的实例,而在XML中这是不可能的(这就是XmlSerializer无法序列化循环引用的原因)。树不是环,循环引用将由某种类型的环表示(实例A引用实例b,实例b引用实例A)。我非常感激使用减号的原因,这样我就可以更正我的回答了Json.net不支持循环引用,据我所知,没有序列化程序支持它们,Json.net可以“展开”引用,但序列化/反序列化对象将不会有循环引用。我正在编写它。@Gusman,是的,就像你说的,当JSON.Net在对象图的另一个位置遇到相同的实例时,它只会删除对原始实例的引用,