Chris James
Chris James

Reputation: 11701

Updating XmlDocument using linq (possibly)

I have an XmlDocument object in memory, here is a sample of the data:

<terms>
<letter name="F">
<term>
  <name>fascículo</name>
  <translation language="en">fascicle</translation>
  <definition>pequeño paquete de fibras nerviosas o musculares</definition>
</term>

(There are many terms in the actual document)

I want to be able to find a term by its name node, and then add an element as a child of the term

<terms>
<letter name="F">
<term>
  <name>fascículo</name>
  <translation language="en">fascicle</translation>
  <definition>pequeño paquete de fibras nerviosas o musculares</definition>
<image>hi there</image>
</term>

Now I can achieve this using Xpath, find the node, then create a new node with the new values, blah blah.

But that seems all a little bit long winded in the world of linq.

This is what I have so far:

        private static XmlDocument AddImages(XmlDocument termDoc)
    {
        XDocument xDoc = XDocument.Load(new XmlNodeReader(termDoc));

        using (CsvReader csv = new CsvReader(new StreamReader("spa2engimages.csv"), false))
        {
            csv.ReadNextRecord();
            csv.ReadNextRecord();
            XElement selectedTerm;

            string name, imageref;

            while (csv.ReadNextRecord())
            {
                imageref = csv[0].ToString();
                name = csv[3].ToString();
                selectedTerm = xDoc.Descendants("term").Single(t => t.Descendants("name").Single().Value == name);

                //now want to add a new node and save it back in to the termDoc somehow
            }
        }

        return termDoc;
    }

But I am a bit lost from there. Any ideas?

Upvotes: 1

Views: 828

Answers (2)

Chris James
Chris James

Reputation: 11701

This is how to do it with xPath, just for clarity

termDoc.SelectSingleNode("//term[name='" + name + "']").AppendChild(imageNode);

Upvotes: 1

Robert MacLean
Robert MacLean

Reputation: 39261

The following will add the element for you

xDoc.Descendants("term").Single(t => t.Descendants("name").Single().Value == name).Add(new XElement("image", "hi there"));

The biggest issue I see which is making this clunky is the fact you need to switch back and forward between XmlDocument and XDocument. My recommendation is if you are going to use XmlDocument then use XPath and if you want to use LINQ then use XDocument. This constant switching will kill performance and maintainability.

Upvotes: 2

Related Questions