SGCSam
SGCSam

Reputation: 71

XML Loop through all childs and subchilds in C++/CLI

At the moment, I'm using XML in order to create a data structure containing many questions for a quiz containing info like the question itself, the answer etc and then for those to be put into variables to be displayed in labels. Here's an example of the XML file:

<?xml version="1.0" encoding="utf-8"?>
<questionData>
    <question>
    <level> 1 </level>
    <ref> ref1 </ref>
    <questionText>This is a test question using XML!</questionText>
    <A>This is A using XML!</A>
    <B>This is B using XML!</B>
    <C>This is C using XML!</C>
    <D>This is D using XML!</D>
    <corrAnswer> A </corrAnswer>
    <APerc> 97 </APerc>
    <BPerc> 1 </BPerc>
    <CPerc> 1 </CPerc>
    <DPerc> 1 </DPerc>
    <PAFAnswer> A </PAFAnswer>
    <PAFFeeling> Sure </PAFFeeling>
    <FF> B </FF>
    <FFcorrPerc> 100 </FFcorrPerc>
    <FFwrongPerc> 0 </FFwrongPerc>
    <FFPAFAnswer> A </FFPAFAnswer>
    <FFPAFFeeling> Sure </FFPAFFeeling>
    <EXP> This is a test explanation for the info box. </EXP>
    <pronuns> pro-nun-cee-a-sh-un </pronuns>
    </question>

    <question>
    <level> 2 </level>
    <ref> ref2 </ref>
    <questionText>This is another test question using XML!</questionText>
    <A>This is A2 using XML!</A>
    <B>This is B2 using XML!</B>
    <C>This is C2 using XML!</C>
    <D>This is D2 using XML!</D>
    <corrAnswer> B </corrAnswer>
    <APerc> 96 </APerc>
    <BPerc> 1 </BPerc>
    <CPerc> 1 </CPerc>
    <DPerc> 2 </DPerc>
    <PAFAnswer> B </PAFAnswer>
    <PAFFeeling> Sure </PAFFeeling>
    <FF> A </FF>
    <FFcorrPerc> 100 </FFcorrPerc>
    <FFwrongPerc> 0 </FFwrongPerc>
    <FFPAFAnswer> B </FFPAFAnswer>
    <FFPAFFeeling> Sure </FFPAFFeeling>
    <EXP> This is another test explanation for the info box. </EXP>
    <pronuns> pro-nun-cee-a-sh-un two </pronuns>
    </question>
</questionData>

Now, I'm intending to have a good number of questions contained in this file. However, the further up the quiz you progress, the harder they get, hence I have included an element called level with a number corresponding to when it will be asked (so for example, you have 15 questions in the quiz, you are on question 3 so it parses the XML file for a question that has the level element as 3, then loads the data into the program).

However, there's a problem - most likely a logic error. In the C++/CLI code, I have this:

         XmlTextReader^ dataFromQFile = gcnew XmlTextReader("Millionaire\\questionsData.xml");
         XmlDocument^ questionsData = gcnew XmlDocument();
         questionsData->Load("Millionaire\\questionsData.xml");
         XmlElement^ root = questionsData->DocumentElement;
         XmlNodeList^ listOfQuestions = root->GetElementsByTagName("questionData");
         XmlNodeList^ Questions = root->GetElementsByTagName("question");

         for each (Questions in listOfQuestions)
         {
             levelFromXML = (root->GetElementsByTagName("level"))->Item(0)->InnerText;
             questionFromXML = (root->GetElementsByTagName("questionText"))->Item(0)->InnerText;
             AFromXML = (root->GetElementsByTagName("A"))->Item(0)->InnerText;
             BFromXML = (root->GetElementsByTagName("B"))->Item(0)->InnerText;
             CFromXML = (root->GetElementsByTagName("C"))->Item(0)->InnerText;
             DFromXML = (root->GetElementsByTagName("D"))->Item(0)->InnerText;
             corrFromXML = (root->GetElementsByTagName("corrAnswer"))->Item(0)->InnerText;
             APercFromXML = (root->GetElementsByTagName("APerc"))->Item(0)->InnerText;
             BPercFromXML = (root->GetElementsByTagName("BPerc"))->Item(0)->InnerText;
             CPercFromXML = (root->GetElementsByTagName("CPerc"))->Item(0)->InnerText;
             DPercFromXML = (root->GetElementsByTagName("DPerc"))->Item(0)->InnerText;
             phoneAnswerFromXML = (root->GetElementsByTagName("PAFAnswer"))->Item(0)->InnerText;
             phoneFeelingFromXML = (root->GetElementsByTagName("PAFFeeling"))->Item(0)->InnerText;
             fiftyAnswer = (root->GetElementsByTagName("FF"))->Item(0)->InnerText;
             fiftyCorrPerc = (root->GetElementsByTagName("FFcorrPerc"))->Item(0)->InnerText;
             fiftyWrongPerc = (root->GetElementsByTagName("FFwrongPerc"))->Item(0)->InnerText;
             fiftyPhoneAnswer = (root->GetElementsByTagName("FFPAFAnswer"))->Item(0)->InnerText;
             fiftyPhoneFeeling = (root->GetElementsByTagName("FFPAFFeeling"))->Item(0)->InnerText;
             exp = (root->GetElementsByTagName("EXP"))->Item(0)->InnerText;
             pronuns = (root->GetElementsByTagName("pronuns"))->Item(0)->InnerText;
         }

As I try to loop through the list of questions (questionData being the parent, question being the child and all the data contained in question being the subchilds), when I try to display the variable in the label, I get no text at all, hence leading me to believe I've made a logic error in the loop. I'm relatively new to XML, so I'm unable to spot my error. Are any of you able to help me out or possibly know of a more efficient way to perform the aforementioned task? Thanks.

Upvotes: 0

Views: 643

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

Your root element (respectively documentElement) is already the questionData element so doing root->GetElementsByTagName("questionData") returns an empty list. If you want to process the question elements in a loop then simply process for each(question in questionsData->GetElementsByTagName("question")) and then inside the loop make sure you call the method on the loop variable e.g. levelFromXML = (question->GetElementsByTagName("level"))->Item(0)->InnerText;.

I would also use https://msdn.microsoft.com/en-us/library/sss31aas%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1 instead of GetElementsByTagName inside of the loop, so you can replace the above snippet simply with levelFromXML = question["level"]->InnerText;.

Upvotes: 1

Related Questions