0

Noobie to the XML/Xdocument world. Trying to create an Xdocument with a variable number of DataField elements which are passed in as a List of Tuples. This document is used as part of an API call to edit fields in a record on a distant server. When I try to add the DataField elements in the foreach loop, xdoc is seen as Null. So I keep getting NullReferenceException errors. Why does xdoc or its XElements = null when I just created it? I know this isn't a difficult situation, but for the last few days I've looked through several sites and it is clear I am not getting something very fundamental.

public XDocument MakeXDoc(string frmID, string prj, List<Tuple<string, string, string>> frmdata)
{
    XNamespace ns = "http://xxxxxxx.yyyyyy.com/api/v1/";
    var xdoc = new XDocument(
         new XDeclaration("1.0", "utf-8", null),
         new XElement(ns + "ProjectDataRequest",
         new XElement(ns + "Project",
         new XElement(ns + "DataFields", new XAttribute("ProjectId", prj), new XAttribute("FormId", frmID),
         new XElement(ns + "DataField" , new XAttribute("DataFieldId", ""), new XAttribute("Value", "") )))));

        foreach (Tuple<string, string, string> fld in frmdata)
        {
            XElement xdf = new XElement(ns + "DataField", new XAttribute("DataFieldId", fld.Item1.ToString()), new XAttribute("Value", fld.Item3.ToString()));
            xdoc.Element(ns + "DataField").Add(xdf);
        }

    return xdoc;
}
nelchr
  • 3
  • 1

1 Answers1

0

It throws the exception, because there isn't an element yet. To build the wanted XML, you could use LINQ's Select:

XDocument MakeXDoc(string frmID, string prj, List<Tuple<string, string, string>> frmdata)
{
    XNamespace ns = "http://xxxxxxx.yyyyyy.com/api/v1/";
    var xdoc = new XDocument(
        new XDeclaration("1.0", "utf-8", null),
        new XElement(ns + "ProjectDataRequest",
        new XElement(ns + "Project",
        new XElement(ns + "DataFields", new XAttribute("ProjectId", prj), new XAttribute("FormId", frmID),
        frmdata.Select(d => new XElement(ns + "DataField", new XAttribute("DataFieldId", d.Item1), new XAttribute("Value", d.Item3)))))));

    return xdoc;
}

It adds a new DataField element for each item in frmdata as child of DataFields.

Sebastian Hofmann
  • 1,440
  • 6
  • 15
  • 21