Good day! How to save data about objects that do not know about other objects into one XML file?

I have the following classes: Test - which does not know about anything other than its data. The question is - who knows about the test for which he was created and about his data. The answer is - who knows about the question to which it was created and about its data.

Test class

[XmlRoot(ElementName = "Test")] public class Test { public int Id { get; set; } public string Name { get; set; } public string Theory { get; set; } public bool IsShowTheory { get; set; } public string URLtoTheory { get; set; } public DateTime Date { get ; set; } public int CountRandomQoestions { get; set; } public int CountCorrectAnswers { get; set; } private Test() { } public Test(int id, string name, string theory, bool isShowTheory, string urlToTheory, DateTime date, int countRandomQuestion, int countCorrectAnswers) { Id = id; Name = name; Theory = theory; IsShowTheory = isShowTheory; URLtoTheory = urlToTheory; Date = date; CountCorrectAnswers = countCorrectAnswers; CountRandomQoestions = countRandomQuestion; } } 

Class question

 [XmlRoot(ElementName = "QUestion")] public class Question { public int Id { get; } [XmlElement("Test", typeof(Test))] public Test Test { get; } public string Text { get; } private Question() { } public Question(int id, Test test, string text) { Id = id; Test = test; Text = text; } } 

Class Answer

  [XmlRoot(ElementName = "Answer")] public class Answer { public int Id { get; set; } [XmlElement("Question", typeof(Question))] public Question Question { get; set; } public string Text { get; set; } public bool IsTrue { get; set; } private Answer() { } public Answer(int id, Question question, string text, bool isTrue) { Id = id; Question = question; Text = text; IsTrue = isTrue; } } 

I create a test like this:

  Test result = new Test(0, "C# basic", "Look in the WIKI", true, @"http:\\Wikipedia.ru", DateTime.Now, 2, 1); Question objectQuestion = new Question(0, result ,"What is the general type?"); Answer objectAnswer1 = new Answer(0, objectQuestion, "string", false); Answer objectAnswer2 = new Answer(1, objectQuestion, "object", true); Answer objectAnswer3 = new Answer(2, objectQuestion, "int", false); Answer objectAnswer4 = new Answer(3, objectQuestion, "bool", false); 

How do these objects serialize to a similar xml file?

 <Test> <Name> Основы C#. </Name> <Theory> Язык C# (c-sharp, си шарп) - современный объектно-ориентированный язык программирования. Он был разработан компанией Microsoft как один из языков для платформы .NET (.NET framework). Язык c# в наше время очень широко развит и продолжает развиваться: в нем появляются новые возможности, языковые конструкции, пополняется библиотека классов. </Theory> <IShowTheory> true </IShowTheory> <URLtoTheory> [url]https://ru.wikipedia.org/wiki/C_Sharp[/url] </URLtoTheory> <CountRandomQuestion> 4 </CountRandomQuestion> <CountCorrectAnswers> 3 </CountCorrectAnswers> <Question> <Text> Какой класс является базовым для всех классов в С#? </Text> <AnswerVariant> <Text> String </Text> <IsTrue> false </IsTrue> </AnswerVariant> <AnswerVariant> <Text> object </Text> <IsTrue> true </IsTrue> </AnswerVariant> <AnswerVariant> <Text> int </Text> <IsTrue> false </IsTrue> </AnswerVariant> <AnswerVariant> <Text> bool </Text> <IsTrue> false </IsTrue> </AnswerVariant> </Question> </Test> 

    2 answers 2

    Add a Question array to the Test class, and remove the Test field from the Question.

     [XmlElement ( ElementName = "Question" )] public Question[ ] Questions; 

    You have a strange, in my opinion, logic. In the code, not a question refers to a test, but a test to a question, and the logic is correct in the xml file.

    • I agree, an array of questions will solve the problem, but the Test should not know anything about the questions. And I did not quite understand where you found in the code that the test relates to the question. Perhaps you are confused by the fields: CountRandomQoestions - how many scientifically selected questions you need to set CountCorrectAnswers - how many correct answers you need to pass the test. In my question they do not play any role. Is it possible to create a similar xml file without tightly binding entities? - Slava Podolskiy
    • The Question class has a Test field. Here it turns out that the test relates to the question. How to do without binding, I unfortunately do not know. Perhaps you describe the problem more specifically - and you can come up with another solution. But notice that in the xml file you have questions contained in the test. And judging by the code, in order to find the test questions, you need to go through all the questions, and select those that correspond to the current test. If there are a lot of tests and questions, it will be very long. - Trymount
    • @SlavaPodolskiy should not mark the answer correct. Maybe it really is possible, I just do not know - Trymount

    If you want to save exactly unrelated objects, you can do this. Create your own serializer for each type of object, open the XmlWriter and manually write the root element. Then you can write any objects there.

     var xsTest = new XmlSerializer(typeof(Test)); var xsQuestion = new XmlSerializer(typeof(Question)); var xsAnswer = new XmlSerializer(typeof(Answer)); var settings = new XmlWriterSettings { Indent = true }; using (var writer = XmlWriter.Create("test.xml", settings)) { writer.WriteStartElement("root"); xsTest.Serialize(writer, result); xsQuestion.Serialize(writer, objectQuestion); xsAnswer.Serialize(writer, objectAnswer1); xsAnswer.Serialize(writer, objectAnswer2); xsAnswer.Serialize(writer, objectAnswer3); xsAnswer.Serialize(writer, objectAnswer4); } 

    It is necessary to read from such xml using again the three serializers of the necessary types. Pre-manually skipping the root element (if the option is interesting, I will write the code).

    The structure of the resulting xml, of course, is not as you need. But in your example, the data in the file is just the same. And for this, as you have been advised, you need to add collection properties to your classes that contain other objects.