Search code examples
c#xmllinqxelement

Insert XML file into existing XML file using LINQ to XML


Using some example code I found here on SO, I've put together a bit of code to open up an existing XML database, open up another XML file that's to be inserted into the first XML, get the descendants of the root node in that file, and append them to the base of the selected node in the database.xml file, and then save the resultant file to a new XML file. The code below compiles & runs with no errors in VS2010, but doesn't add the XML from the actionID.xml file to the database.xml file and I don't know what I'm missing.

Here's the C# code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

class pcbdbUpdate
{
static void Main( )
    {
        //open database & load into memory
        XDocument PCBDB = XDocument.Load("C:\\database.xml");
        //open Activity Log file & load into memory
        XDocument addAction = XDocument.Load("C:\\actionID.xml");
        //get descendant node(s) below PCBDBActivityLog root node
        var actionXML = addAction.Root.Descendants("PCBDBActivityLog");
        /*supposed to write out child nodes, but not very useful, just tells me
        it's a:  System.Xml.Linq.XContainer+<GetDescendants>d__a*/
        Console.WriteLine(actionXML.ToString());
        //enumerate database for SBE_PCB_Data nodes
        IEnumerable<XElement> SBE_PCB_Data = PCBDB.Element("PCBDatabase").Elements("SBE_PCB_Data");
        //look for specific node with PCBID of "00001" and select it
        XElement newAction = SBE_PCB_Data.Where(p => p.Attribute("PCBID").Value == "00001").FirstOrDefault();
        //write descendants from Activity Log to base of node
        newAction.Add(actionXML);
        //save the resultant file
        PCBDB.Save("C:\\newDatabase.xml");
    }
}

Here's the database.xml:

<?xml version="1.0" encoding="utf-8"?>
<PCBDatabase>
  <SBE_PCB_Data PCBID="00001">
    <Creation ActionID="0002" User="DELLIOTTG:192.168.1.69" Date="2012-10-31T14:35:58" PCBID="00001">
      <PCBDrawing>00001a</PCBDrawing>
      <AssemblyDrawing>00001b</AssemblyDrawing>
      <Vendor>SBE</Vendor>
      <PONumber>00000</PONumber>
    </Creation>
    <Assignment ActionID="1295" User="RHO:192.168.1.6" Date="2012-12-13T08:59:31" PCBID="00001">
      <PCBDrawing>00002a</PCBDrawing>
      <AssemblyDrawing>00001c</AssemblyDrawing>
      <Vendor>SBE</Vendor>
      <PONumber>00001</PONumber>
    </Assignment>   
  </SBE_PCB_Data>
  <SBE_PCB_Data PCBID="00002">
    <Assignment ActionID="630c" User="DMUELLER:192.168.1.152" Date="2010-03-15T13:14:21" PCBID="00002">
      <SBEJobNumber>57380</SBEJobNumber>
    </Assignment>
  </SBE_PCB_Data>
</PCBDatabase>

And here's the actionID.xml:

<?xml version="1.0"?>
<PCBDBActivityLog>
    <Assignment ActionID='8353' User='DMUELLER:192.168.1.134' Date='2011-01-27T15:38:25' PCBID='00001'>
        <SBEPN>41528E</SBEPN>
    </Assignment>
</PCBDBActivityLog>

The resultant file should look like this:

<?xml version="1.0" encoding="utf-8"?>
<PCBDatabase>
  <SBE_PCB_Data PCBID="00001">
    <Creation ActionID="0002" User="DELLIOTTG:192.168.1.69" Date="2012-10-31T14:35:58" PCBID="00001">
      <PCBDrawing>00001a</PCBDrawing>
      <AssemblyDrawing>00001b</AssemblyDrawing>
      <Vendor>SBE</Vendor>
      <PONumber>00000</PONumber>
    </Creation>
    <Assignment ActionID="1295" User="RHO:192.168.1.6" Date="2012-12-13T08:59:31" PCBID="00001">
      <PCBDrawing>00002a</PCBDrawing>
      <AssemblyDrawing>00001c</AssemblyDrawing>
      <Vendor>SBE</Vendor>
      <PONumber>00001</PONumber>
    </Assignment>
    <Assignment ActionID='8353' User='DMUELLER:192.168.1.134' Date='2011-01-27T15:38:25' PCBID='00001'>
        <SBEPN>41528E</SBEPN>
    </Assignment>
  </SBE_PCB_Data>
  <SBE_PCB_Data PCBID="00002">
    <Assignment ActionID="630c" User="DMUELLER:192.168.1.152" Date="2010-03-15T13:14:21" PCBID="00002">
      <SBEJobNumber>57380</SBEJobNumber>
    </Assignment>
  </SBE_PCB_Data>
</PCBDatabase>

What am I missing or doing wrong?


Solution

  • Error is here:

    var actionXML = addAction.Root.Descendants("PCBDBActivityLog")` 
    

    You are trying to find <PCBDBActivityLog> elements under the document root. But this will return nothing, because <PCBDBActivityLog> element is a root of actionID.xml document. Replace this line with

    var actionXML = addAction.Descendants("PCBDBActivityLog");
    

    Or

    var actionXML = addAction.Root;