0

I have a method that is suppose to edit a xml file:

    public void EditItem(Item item, string xml)
    {
        Data = XDocument.Load(HttpContext.Current.Server.MapPath("~/App_Data/Items/" + xml + ".xml"));

        XElement node = Data.Root.Elements("item").Where(i => (string)i.Element("ID") == item.ID).FirstOrDefault();

        node.SetElementValue("ID", item.ID);
        node.SetElementValue("Name", item.Name);
        node.SetElementValue("Type", item.Type);
        node.SetElementValue("Kr", item.Kr);
        node.SetElementValue("Euro", item.Euro);

        Data.Save(HttpContext.Current.Server.MapPath("~/App_Data/Tables/" + xml + ".xml"));
    }

I get this validation error thru a try/catch in my controller: "Object reference not set to an instance of an object." Through some debugging, I found that "node" is null, even though "Data" contains all the right data from the xml, and the model.ID is correct.

the wierd thing is, that I have it working in another repo where the xml isnt dynamic, and the XDocument obj is loaded in the constructor.

Any ideas what causes it? Or maybe some ideas on a workaround.

Update. Xml snippet:

<?xml version="1.0" encoding="utf-8"?>
    <catagory id="0">
      <module>
        <item>
          <ID>101</ID>
          <Name>ClassicoTable(35x100x100)</Name>
          <Type>Model</Type>
          <Kr>0</Kr>
          <Euro>0</Euro>
          <DataType>ClassicoTableA</DataType>
        </item>
        <item>
          <ID>100</ID>
          <Name>ClassicoTable(102x100x140)</Name>
          <Type>Model</Type>
          <Kr>0</Kr>
          <Euro>0</Euro>
          <DataType>ClassicoTableB</DataType>
        </item> 



       ......

      </module>
    </catagory id="0">
9
  • the wierd thing is, that I have it working in another repo where the xml isnt dynamic, and the XDocument obj is loaded in the constructor. Commented Aug 30, 2011 at 13:41
  • where does table in table.ID come from? Commented Aug 30, 2011 at 13:42
  • Can you show a snippet from your xml file? Commented Aug 30, 2011 at 13:43
  • 2
    Of course, this question has nothing to do with MVC. Commented Aug 30, 2011 at 13:45
  • Just a small note here, if you expect to always get a node you might change the FirstOrDefault() to First(). Otherwise you express to be ok with null values, but need to check it on the next line. Commented Aug 30, 2011 at 13:56

2 Answers 2

1

Should this line:

XElement node = Data.Root.Elements("item").Where(i => (string)i.Element("ID") == table.ID).FirstOrDefault();

be this (not sure where table.ID comes from):

XElement node = Data.Root.Elements("item").Where(i => (string)i.Element("ID") == item.ID).FirstOrDefault();

I would also check if node is null:

public void EditItem(Item item, string xml)
{
    Data = XDocument.Load(HttpContext.Current.Server.MapPath("~/App_Data/Items/" + xml + ".xml"));

    XElement node = Data.Root.Elements("item").Where(i => (string)i.Element("ID") == item.ID).FirstOrDefault();

    if (node != null)
    {
        node.SetElementValue("ID", item.ID);
        node.SetElementValue("Name", item.Name);
        node.SetElementValue("Type", item.Type);
        node.SetElementValue("Kr", item.Kr);
        node.SetElementValue("Euro", item.Euro);

        Data.Save(HttpContext.Current.Server.MapPath("~/App_Data/Tables/" + xml + ".xml"));
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

woops. Yes table is item ofcourse :) The code is not directly from my app. So thats not an issue :)
But yes, adding the if statement is good if I wanna avoid the error. The problem is that the error shouldnt be there, and really doesnt solve the fact that the method doesnt work. Thanks for the quick answer!
0

Okay found a solution. I started wondering why @Kim wanted a snippet from my xml. So it made me think that Data.Root.Element() maybe wasnt the right way. So I tried with Descendants() instead, and that actually works. Why? I have no clue. Heres why:

In another repo I have the XDocument.load() in the constructor of the repo. I thought that would be good, because then I wouldnt have to repeat the same code in all the CRUD methods. But, as I wanted the xml dynamic, and the constructor doesnt accept parameters, I thought this way (original question) would be fine. Here the code from the "static" repo:

//Constructor
public CubeRepository()
{
    allCubes = new List<Cube>();

    CubeData = XDocument.Load(HttpContext.Current.Server.MapPath("~/App_Data/Cubes/Cubep10p11.xml"));
    var cubes = from cube in CubeData.Descendants("item")
                select new Cube(cube.Element("ID").Value, 
                    cube.Element("Name").Value, 
                    cube.Element("Type").Value,
                    (int)cube.Element("Kr"),
                    (int)cube.Element("Euro"));

    allCubes.AddRange(cubes.ToList<Cube>());
}

And in my edit method of that repo:

public void EditCube(Cube cube)
{
    XElement node = CubeData.Root.Elements("item").Where(i => (string)i.Element("ID") == cube.ID).FirstOrDefault();
    node.SetElementValue("ID", cube.ID);
    node.SetElementValue("Name", cube.Name);
    node.SetElementValue("Type", cube.Name);
    node.SetElementValue("Kr", cube.Kr);
    node.SetElementValue("Euro", cube.Euro);

    CubeData.Save(HttpContext.Current.Server.MapPath("~/App_Data/Cubes/Cubep10p11.xml"));
}

And that works like I charm, even though im using CubeData.Root.Elements("item"). Note: Elements insted of Descendants. The structure of the xml files are identical.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.