3

I'm trying to get the value out of my XML element and convert it to an integer using linq commands so I can do some mathematical equations using it.

This is how I've tried it so far:

private void buttonTab4Mod1Calculate_Click(object sender, EventArgs e)
        {
            var document = XDocument.Load(workingDir + @"\Level4.xml");

            var assessmentOneWeight = from d in document.Descendants("moduleTitle")
                                      where d.Value == (String)comboBoxTab4Mod8.SelectedItem
                                      select d.Parent.Element("assessmentOneWeight").Value;
            int a = 0;
            foreach (var item in assessmentOneWeight)
            {
                a = Convert.ToInt32(item);
            }
            MessageBox.Show(a.ToString());
        }

but the value is still 0 for some reason.

This is my xml file:

<?xml version="1.0" encoding="utf-8" ?>
<SoftwareEngineering>
  <Module>
    <moduleCode>ECSE401</moduleCode>
    <moduleTitle>Programming Methodology</moduleTitle>
    <credits>15</credits>
    <assessmentOne>Coursework</assessmentOne>
    <assessmentOneWeight>40</assessmentOneWeight>
    <assessmentTwo>Coursework</assessmentTwo>
    <assessmentTwoWeight>40</assessmentTwoWeight>
    <assessmentThree>Test</assessmentThree>
    <assessmentThreeWeight>20</assessmentThreeWeight>
  </Module>
  <Module>
    <moduleCode>ECSC404</moduleCode>
    <moduleTitle>Computer Systems Fundamentals</moduleTitle>
    <credits>15</credits>
    <assessmentOne>Test1</assessmentOne>
    <assessmentOneWeight>30</assessmentOneWeight>
    <assessmentTwo>Test2</assessmentTwo>
    <assessmentTwoWeight>30</assessmentTwoWeight>
    <assessmentThree>Test3</assessmentThree>
    <assessmentThreeWeight>40</assessmentThreeWeight>
  </Module>
  <Module>
    <moduleCode>EBSY401</moduleCode>
    <moduleTitle>Information and Data Modelling</moduleTitle>
    <credits>15</credits>
    <assessmentOne>Test</assessmentOne>
    <assessmentOneWeight>25</assessmentOneWeight>
    <assessmentTwo>Coursework1</assessmentTwo>
    <assessmentTwoWeight>10</assessmentTwoWeight>
    <assessmentThree>Coursework2</assessmentThree>
    <assessmentThreeWeight>35</assessmentThreeWeight>
    <assessmentFour>Coursework3</assessmentFour>
    <assessmentFourWeight>30</assessmentFourWeight> 
  </Module>
  <Module>
    <moduleCode>ECSC405</moduleCode>
    <moduleTitle>Software Development Principles</moduleTitle>
    <credits>15</credits>
    <assessmentOne>Test1</assessmentOne>
    <assessmentOneWeight>30</assessmentOneWeight>
    <assessmentTwo>Coursework</assessmentTwo>
    <assessmentTwoWeight>40</assessmentTwoWeight>
    <assessmentThree>Test2</assessmentThree>
    <assessmentThreeWeight>30</assessmentThreeWeight>
  </Module>
  <Module>
    <moduleCode>ECSC407</moduleCode>
    <moduleTitle>Web Technology</moduleTitle>
    <credits>15</credits>
    <assessmentOne>Tutorials</assessmentOne>
    <assessmentOneWeight>20</assessmentOneWeight>
    <assessmentTwo>Coursework</assessmentTwo>
    <assessmentTwoWeight>20</assessmentTwoWeight>
    <assessmentThree>Exam</assessmentThree>
    <assessmentThreeWeight>60</assessmentThreeWeight>
  </Module>
  <Module>
    <moduleCode>ECSC409</moduleCode>
    <moduleTitle>Software Engineering Principles</moduleTitle>
    <credits>15</credits>
    <assessmentOne>Coursework1</assessmentOne>
    <assessmentOneWeight>40</assessmentOneWeight>
    <assessmentTwo>Coursework2</assessmentTwo>
    <assessmentTwoWeight>30</assessmentTwoWeight>
    <assessmentThree>Coursework3</assessmentThree>
    <assessmentThreeWeight>30</assessmentThreeWeight>
  </Module>
  <Module>
    <moduleCode>ECSC408</moduleCode>
    <moduleTitle>Mathematics for Computing</moduleTitle>
    <credits>15</credits>
    <assessmentOne>Coursework</assessmentOne>
    <assessmentOneWeight>50</assessmentOneWeight>
    <assessmentTwo>Exam</assessmentTwo>
    <assessmentTwoWeight>50</assessmentTwoWeight>
  </Module>
  <Module>
    <moduleCode>EBSY400</moduleCode>
    <moduleTitle>Communication and Learning Skills</moduleTitle>
    <credits>15</credits>
    <assessmentOne>Coursework</assessmentOne>
    <assessmentOneWeight>30</assessmentOneWeight>
    <assessmentTwo>Coursework</assessmentTwo>
    <assessmentTwoWeight>70</assessmentTwoWeight>
  </Module>
</SoftwareEngineering>

Would greatly appreciate some help.

a7omiton
  • 1,597
  • 4
  • 34
  • 61
  • Are you sure `assessmentOneWeight` is returning something? Your message box is outside the main loop, and we can't be sure there are any results at all coming back. – yamen Apr 15 '12 at 22:00
  • 2
    Do you try to make your homework/job using SO without making something by your own? I recall at least 3 questions with the same xml – L.B Apr 15 '12 at 22:00
  • Same thing in your past questions also. For ex, http://stackoverflow.com/questions/9954060/how-to-match-elements-in-xml-c-sharp – L.B Apr 15 '12 at 22:06
  • its not the same thing, its using the same thing but functionality is different. and I am trying it out before I ask but since I'm a noob to programming its helping me get a better understanding of what could/should happen if you want to do things a certain way. its homework – a7omiton Apr 16 '12 at 10:47

2 Answers2

5

Just cast the XElement to int:

private void buttonTab4Mod1Calculate_Click(object sender, EventArgs e)
{
    var document = XDocument.Load(workingDir + @"\Level4.xml");

    string selectedItem = (string) comboBoxTab4Mod8.SelectedItem;
    var assessmentOneWeight = from d in document.Descendants("moduleTitle")
                              where (string) d == selectedItem
                              select (int) d.Parent.Element("assessmentOneWeight");
    foreach (int item in assessmentOneWeight)
    {
         MessageBox.Show(item.ToString());
    }        
}

Note that you can also cast to int? which works the same way when the reference does is an XElement, but if you cast a null reference to int? you get a null value back - which can be helpful if you don't know whether there is a corresponding element or not.

There are lots of explicit conversions for XElement, and XAttribute too - they make life a lot easier.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks Jon, so now that I've got the value out I'm going to declare an int variable outside the foreach loop and inside the foreach loop make the variable's value equal to item, that way I can do my math equations. – a7omiton Apr 16 '12 at 10:57
  • @AZ1: That doesn't make much sense to me - is it one value *per element* (in which case declare it inside the loop) or one value which is modified *based on the value of the element* (e.g. to create a total)? If you *just* set it to the item's value, then you're effectively saying "I only care about the last element". – Jon Skeet Apr 16 '12 at 10:59
  • What I'm wanting to do is get out the value of this element which the user will pick, and since I don't know which one they will pick I need to declare it in a foreach loop. I'm going to use the value (which is the percentage weight the assessment weighs for the total module grade) and divide it by 100 and multiply that by another value entered by the user in a textbox (indicating what grade they expect to get). – a7omiton Apr 16 '12 at 18:45
  • @AZ1: But you've already *found* the one that the user's picked, in the `where` clause. So presumably the resulting sequence should only have one element, right? – Jon Skeet Apr 16 '12 at 18:46
1

I'm pretty sure that your assessmentOneWeight collection does not contain a single value because the value of comboBoxTab4Mod8.SelectedItem cannot be found in the XML.

Therefore you always get 0, because a is initialized with 0.


BTW: I strongly recommend you to improve your code.

Iterate over the <Module> element instead of the <moduleTitle> element. This makes more sense as you need the data of this element (namely <assessmentOneWeight>)

Cast the value of <assessmentOneWeight> directly in your LINQ statement, like this:

var assessmentOneWeight =
    from d in document.Descendants("moduleTitle")
    where d.Value == (String)comboBoxTab4Mod8.SelectedItem
    select int.Parse(d.Parent.Element("assessmentOneWeight").Value);

Your foreach is not well designed as it takes only the last value found in your collection. If you really want that value use the power of LINQ and select only that value.

CodeZombie
  • 5,367
  • 3
  • 30
  • 37
  • the reason I was using '' was because I thought I needed that to compare with the selected item in the combo box, I didn't know you could select the parent '' and compare it to the combo box value as well – a7omiton Apr 16 '12 at 10:40