【发布时间】:2015-07-08 16:58:46
【问题描述】:
短版:我需要能够序列化/反序列化 XML 并根据我设置的自定义 Id 维护引用。我需要一些通用的东西,可以通过在序列化后构建引用来做到这一点,或者最好自定义一个 C# 序列化程序来处理这个问题。
我正在创建一个需要与各种应用程序通信的 WCF 应用程序。我们基本上是在构建一个非常复杂的计算器。我们确实有一个公共数据库,但是,用户对象的状态可能与数据库中的状态不同,我们不想存储这个中间状态。
我需要能够在 XML 中传递复杂的相关对象(请参阅 WCF),这些对象使用自定义的引用构建器。构建器需要根据每个对象具有的 Id 将对象重新组合在一起。我希望能够指定 id,以便另一个应用程序(例如 C++)可以通过正确构建 XML 来调用我们的应用程序。
我知道 XmlSerializer 只会复制整个引用,而 DataContractSerializer 会保持引用完整性,但它会在现场创建一个标识符。 如何在序列化期间或序列化后解决这些引用?
如果答案是“你不能”,那么我提出以下问题。
目前我们已经构建了一个自定义序列化程序,但速度很慢(XmlSerializer 根据文件大小快 8-30 倍)。我们的自定义序列化程序可以处理以下 XML,但它还有一个解析引用的第二步(在反序列化之后)。但是我将不得不进行一些重大的返工和定制以使 XmlSerializer 能够使用它,因为我们需要 XmlSerializer 的性能。 (即使用 id 列表并在我们所有的引用类上使用 XmlIgnore 解析这些引用)。 是否有任何工具或库已经为 XML 执行此操作,无论是解析步骤还是序列化步骤?
编辑:当我反序列化它时,我需要维护这些引用。如果我在课堂上更改教师姓名,它应该更改学校中的教师姓名。
我已经将我正在谈论的内容的简化版本和我想用来解析它的 XML 放在一起。
public class Teacher
{
//This is a made up annotation that represents what I'd like to happen.
[DataMember(IsReferenceId = True)]
public int Id { get; set; }
public string Name { get; set; }
//This is a made up annotation that represents what I'd like to happen.
[DataMember(IsReference = True)]
public List<Class> Classes { get; set; }
public Teacher()
{
Classes = new List<Class>();
}
public Teacher(int id)
{
Classes = new List<Class>();
Id = id;
}
}
public class Class
{
//This is a made up annotation that represents what I'd like to happen.
[DataMember(IsReferenceId = True)]
public int Id { get; set; }
public string Subject { get; set; }
//This is a made up annotation that represents what I'd like to happen.
[DataMember(IsReference = True)]
public Teacher Teacher { get; set; }
public Class()
{}
public Class(int id)
{
Id = id;
}
}
public class School
{
public string Name { get; set; }
public List<Class> Classes { get; set; }
public List<Teacher> Teachers { get; set; }
}
我希望能够像这样解析 XML。
<School>
<Classes>
<Class>
<Id>1</Id>
<Subject>Biology</Subject>
<Teacher><Id>1</Id></Teacher>
</Class>
<Class>
<Id>2</Id>
<Subject>Advanced Biology</Subject>
<Teacher><Id>1</Id></Teacher>
</Class>
<Class>
<Id>3</Id>
<Subject>Algebra</Subject>
<Teacher><Id>2</Id></Teacher>
</Class>
<Class>
<Id>4</Id>
<Subject>Trigonometry</Subject>
<Teacher><Id>2</Id></Teacher>
</Class>
</Classes>
<Teachers>
<Teacher>
<Id>1</Id>
<Name>Biology Teacher</Name>
<Classes>
<Class><Id>1</Id></Class>
<Class><Id>2</Id></Class>
</Classes>
</Teacher>
<Teacher>
<Id>2</Id>
<Name>Biology Teacher</Name>
<Classes>
<Class><Id>3</Id></Class>
<Class><Id>4</Id></Class>
</Classes>
</Teacher>
</Teachers>
</School>
我没有包含任何反序列化或序列化它的代码,因为实现会根据使用的序列化程序而有所不同。但目前我正在使用带有 [XmlIgnore] 而不是 [DataContract(IsReference = True)] 的 XmlSerializer。但是,我需要将这些引用放回原处。
注意:JSON 不是一个选项,但我们可以使用任何序列化 Xml 的开源库。
【问题讨论】:
标签: c# xml wcf xmlserializer datacontractserializer