Question:
Help to deal with the cycle and xml. This is my first question, I'm a student, I'm trying to write a program to create a test for classmates. I created a form, dynamically created boxes and checkboxes in it. Screenshot . You can add as many tabs as you like…
I need to get the following result:
<test>
<head>NAME OF THE TEST 2017</head>
<description>Тест по Математики за 2016 год</description>
<qw>
<q text="how match 2+2" src="">
<a right="no">1</a>
<a right="no">1,5</a>
<a right="no">45</a>
<a right="yes">4</a>
</q>
<q text="Наше главное преимущество в том, что каждое тестирование уникально....х." src="">
<a right="no">Вика</a>
<a right="no">Настя</a>
<a right="yes">Катя</a>
</q>
.....
.... остальные вопросы N число....
.....
</qw>
<levels>
<level score="1" text="Тест пройден" />
</levels>
</test>
I use for
to collect data from boxes by accessing the TabControl
:
XDocument xdoc = new XDocument();
XElement testXML = new XElement("test");//заголовок
XElement headXML = new XElement("head","заголовок XML");//заголовок
XElement discriptionXML = new XElement("Discriptions","ОПИСАНИЕ ТЕСТА");//описание теста
XElement qwXML = new XElement("qw");//начала вопросов
XElement questionXMLX = new XElement("q");// начало вопроса
XElement questionXMLAY = new XElement("a");// ответ
XElement questionXMLAN = new XElement("a");// ответ
XAttribute DiscriptionAttr = new XAttribute("text", "ПУСТО");//собираем текст
XAttribute questionXAttr = new XAttribute("text", "ПУСТО");//собираем текст
XAttribute questionSRCXAttr = new XAttribute("src", "ПУСТО");//собираем картинку
XAttribute questionAAttrN = new XAttribute("right", "no");//собираем текст
XAttribute questionAAttrY = new XAttribute("right", "yes");//собираем текст
// TextBoxQuest.Tag = "TxBOXquery"; //Поле вопроса
//RadioButton[i].Tag = "rbAnswer"; //Радиобуттон правильного ответа
//TextBoxAns[i].Tag = "TxBOXAnswer";//Варианты ответа
questionXMLAY.Add(questionAAttrY);
questionXMLAN.Add(questionAAttrN);
string ctrl ="";//собираем текст из полей
string tagz = ""; //смотрим что это за поле
int qcount = tabControl1.TabCount * (CountAnswerInTest*2);
for (int itab = 0; itab < tabControl1.TabCount; itab++)//перебираем табы
{
for (int i = 0; i <= CountAnswerInTest*2; i++)//перебираем внутренние ответы
{
ctrl = tabControl1.Controls[itab].Controls[i].Text;//собираем текст из полей
tagz = tabControl1.Controls[itab].Controls[i].Tag.ToString(); //смотрим что это за поле
Console.WriteLine(tagz);//debug
if (tagz == "TxBOXquery") //если равно TxBOXquery то это поле с вопросом
{
Console.WriteLine(ctrl);//debug
Console.WriteLine(questionXMLX);//debug
questionXMLX.Add(ctrl);//Добавляем его
Console.WriteLine(questionXMLX);//debug
}//пишем вопрос
if (tagz == "rbAnswer")//если равно rbAnswer то это поле с ответом
if (ctrl == "")//если текста нет, то скорее всего это радиобуттон\
{
Control ctrlb = tabControl1.Controls[itab].Controls[i]; //присваем чекбокс
if (Convert.ToString(ctrlb) == "System.Windows.Forms.RadioButton, Checked: False") //смотрим нажат или нет
{
Console.WriteLine("False");//debug
// questionXMLA.Add(questionAAttrN);
int ix = ++i;//убираем непонятные пустые поля
string ctrlX = tabControl1.Controls[itab].Controls[ix].Text;//собираем текст из полей
questionXMLX.Add(questionXMLAN, ctrl, ctrlX); //добавляем в xml
}
else //если чекбокс не нажат то пишем NO
{
int ix = ++i;//убираем непонятные пустые поля
string ctrlX = tabControl1.Controls[itab].Controls[ix].Text;//собираем текст из полей
Console.WriteLine("True");//debug
questionXMLX.Add(questionXMLAN, ctrl, ctrlX);/ добавляем в xml
// questionXMLA.Add(questionAAttrY);
}
}
}
qwXML.Add(questionXMLX);// добавляем всё в блок <qw>
}//закончили перебирать табы
testXML.Add(headXML);
testXML.Add(discriptionXML);
testXML.Add(qwXML);
xdoc.Add(testXML);
xdoc.Save("myXML2.xml");
And I get the following result:
<?xml version="1.0" encoding="utf-8"?>
<test>
<head>заголовок XML</head>
<Discriptions>ОПИСАНИЕ ТЕСТА</Discriptions>
<qw>
<q>Пишем вопрос тут 11
<a right="no" />Ответ 10
<a right="no" />Ответ 11
<a right="no" />Ответ 12Пишем вопрос тут 22
<a right="no" />Ответ 20
<a right="no" />Ответ 21
<a right="no" />Ответ 22Пишем вопрос тут 33
<a right="no" />Ответ 30
<a right="no" />Ответ 31
<a right="no" />Ответ 32</q>
<q>Пишем вопрос тут 11
<a right="no" />Ответ 10
<a right="no" />Ответ 11
<a right="no" />Ответ 12Пишем вопрос тут 22
<a right="no" />Ответ 20
<a right="no" />Ответ 21
<a right="no" />Ответ 22</q>
<q>Пишем вопрос тут 11
<a right="no" />Ответ 10
<a right="no" />Ответ 11
<a right="no" />Ответ 12Пишем вопрос тут 22
<a right="no" />Ответ 20
<a right="no" />Ответ 21
<a right="no" />Ответ 22Пишем вопрос тут 33
<a right="no" />Ответ 30
<a right="no" />Ответ 31
<a right="no" />Ответ 32</q>
</qw>
</test>
The error occurs here, no new question is added, although the loops work fine and questionXMLX.Add(ctrl)
fires, which should add a new <q>
:
<a right="no" />Ответ 12Пишем вопрос тут 22
And it needs to be like this:
<a right="no" />Ответ 12</q>
<q>Пишем вопрос тут 22
I don't understand why it doesn't work:
Console.WriteLine(ctrl);//debug
Console.WriteLine(questionXMLX);//debug
questionXMLX.Add(ctrl);//Добавляем его в xml
Console.WriteLine(questionXMLX);//debug
Help me please.
Answer:
This happens because the same XElement is used. One new XElement("q") is equivalent to <\q>. To solve your problem, you need to create a new XElement every time, and at the end of the loop iteration add qwXML.Add(questionXMLX) to the collection.
Something like this:
XElement questionXMLX = new XElement("q");
// Логика по заполнению questionXMLX
qwXML.Add(questionXMLX);
To better understand the logic of interaction with XElement, here is an example of code and XML, which is the result:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144",
new XAttribute("Type", "Home")),
new XElement("phone", "425-555-0145",
new XAttribute("Type", "Work")),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
At the exit:
<?xml version="1.0" encoding="utf-8"?>
<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone Type="Home">206-555-0144</Phone>
<phone Type="Work">425-555-0145</phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
</Contact>
</Contacts>