Search code examples
c#xmllinq-to-xmlxelement

How to iterate through XElement Nodes of XDocument and add to another XElelement?


I have a XML document that looks like this:

<Person>
  <LastName>LastName1</LastName>
  <FirstName>FirstName1</FirstName>
  <MiddleName>MiddleName1</MiddleName>
</Person>

Originally I had a method to create this structure like below:

public XElement ToXML()
{
  return new XElement("Person",
    new XElement(this.LastName.ToXML()),
    new XElement(this.FirstName.ToXML()),
    new XElement(this.MiddleName.ToXML()));
}

The problem is there are a lot of other nodes other than just Person that use the Name values within the root. So what I tried doing was refactoring out the FirstName, LastName, and MiddleName elements to be in their own reusable class with a ToXMLDoc() method that returns those elements as a XDocument instead of a XElement (since the root will be dictated by the class needing the name children; might be Person, Employee, etc.)

This is what my new ToXMLDoc returns:

return new XDocument(new XElement(this.LastName.ToXML()),
                     new XElement(this.FirstName.ToXML()),
                     new XElement(this.MiddleName.ToXML()));

My problem is I want to now add this content to within the root XElement added by my Person class. I tried doing something like below, but I'm not using the constructor properly and getting a "Ambiguous constructor reference" error.

return new XElement("Person",
    foreach (XElement xe in NameType.ToXMLDoc().Nodes())
    {
      new XElement(xe.Value);
    }
);

How can I take the contents from the ToXMLDoc() method and add them to the XElement node being created for Person? Any help is appreciated, thanks!


Solution

  • You're currently trying to embed a foreach loop within a constructor call. That's not going to work - but it's actually pretty simple:

    return new XElement("Person", NameType.ToXMLDoc()
                                          .Nodes()
                                          .Select(xe => new XElement(xe.Value));
    

    Are you sure you don't just want to copy the elements wholesale though? In which case it would just be:

    return new XElement("Person", NameType.ToXMLDoc().Nodes());