Home > other >  Using C# to copy different nodes from two files and pasting it on a third one
Using C# to copy different nodes from two files and pasting it on a third one

Time:09-16

I have a task that is very cumbersome, as I have to do it by hand (my company bought a tool for a ludicrous amount of money that doesn't work anymore).

I have two XML lists, each of them has half of it missing, so I need to piece it together into a third one before sending it to the system. As well as changing the header to the date I'm sending the file.

I've managed to set up the input for the date, it's easy enough to ask the user for the input. But the rest of the task is driving me mad, I tried many things I've found around here and on the Microsoft forums, to no avail... this task is killing me because I'm the only one that is "tech savvy" to do it (it's literally monkey job of copying and pasting text from XMLs).

It's not trucks and cars, obviously, and there are more files than two, but they all are like this: one kind has only cars, with an empty truck node, and the other has trucks but with empty cars node.

Cheers, and thanks for your attention - sorry for the English, it's not my mother tongue.

Example of File 1

<?xml version="1.0" encoding="utf-8"?>
<document>
<header>
    <startDate>01/01/2020</startDate>
    <endDate>01/02/2020</endDate>
</header>
<body>
    <cars>
        <car>
            <ID>1</ID>
            <Name>Blue Car</Name>
        </car>
        <car>
            <ID>2</ID>
            <Name>Red Car</Name>
        </car>
    </cars>
    <trucks>
    </trucks>
</body>
</document>

Example of File 2

<?xml version="1.0" encoding="utf-8"?>
<document>
<header>
    <startDate>01/01/2020</startDate>
    <endDate>01/02/2020</endDate>
</header>
<body>
    <cars>
    </cars>
    <trucks>
        <truck>
            <ID>1</ID>
            <Name>Blue Truck</Name>
        </truck>
        <truck>
            <ID>2</ID>
            <Name>Red Truck</Name>
        </truck>
    </trucks>
</body>
</document>

Example of File 3

<?xml version="1.0" encoding="utf-8"?>
<document>
<header>
    <Date>03/02/2020</Date>
</header>
<body>
    <cars>
        <car>
            <ID>1</ID>
            <Name>Blue Car</Name>
        </car>
        <car>
            <ID>2</ID>
            <Name>Red Car</Name>
        </car>
    </cars>
    <trucks>
        <truck>
            <ID>1</ID>
            <Name>Blue Truck</Name>
        </truck>
        <truck>
            <ID>2</ID>
            <Name>Red Truck</Name>
        </truck>
    </trucks>
</body>
</document>

CodePudding user response:

Use XSLT:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="*">
    <xsl:copy><xsl:apply-templates/></xsl:copy>
  </xsl:template>
  <xsl:template match="cars">
    <cars>
      <xsl:copy-of select="car"/>
      <xsl:copy-of select="document('other-doc.xml')//car"/>
    </cars>
  </xsl:template>
  <xsl:template match="trucks">
    <trucks>
      <xsl:copy-of select="truck"/>
      <xsl:copy-of select="document('other-doc.xml')//truck"/>
    </trucks>
  </xsl:template>
</xsl:transform>

This can of course be run very easily using from C# using the System.Xml.Xsl processor.

I haven't tried to do anything with the dates in the header because I'm not sure what your logic is, but that's easily added.

If you want to use a later version of XSLT it becomes a little shorter but then you need to install a third-party library:

<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:mode on-no-match="shallow-copy"/>
  <xsl:template match="cars">
    <cars>
      <xsl:copy-of select="car, doc('other-doc.xml')//car"/>
    </cars>
  </xsl:template>
  <xsl:template match="trucks">
    <trucks>
      <xsl:copy-of select="truck, doc('other-doc.xml')//truck"/>
    </trucks>
  </xsl:template>
</xsl:transform> 

CodePudding user response:

Please use below code 
 string xml1 = @"<document><header><startDate>01/01/2020</startDate><endDate> 01/02/ 2020</endDate></header><body><cars><car><ID>1</ID><Name>Blue Car</Name></car><car><ID>2</ID><Name>Red Car</Name></car></cars><trucks></trucks></body></document>";
            //load xml in StringReader
            StringReader sr = new StringReader(xml1);
            DataSet ds1 = new DataSet();
            // Read XML in ds1
            ds1.ReadXml(sr);

            string xml2 = @"<document><header><startDate> 01 / 01 / 2020 </startDate><endDate> 01 / 02 / 2020</endDate></header><body><cars></cars><trucks><truck><ID> 1 </ID><Name> Blue Truck </Name></truck><truck><ID>2</ID><Name>Red Truck</Name></truck></trucks></body></document>";
            sr = new StringReader(xml2);
            DataSet ds2 = new DataSet();
            ds2.ReadXml(sr);
            DataSet dsHeaders = new DataSet();
            dsHeaders.Tables.Add(ds1.Tables[0].Copy());
            string headersXML = dsHeaders.GetXml();
            headersXML = headersXML.Replace("<NewDataSet>", "").Replace("</NewDataSet>", "");
            //  Console.WriteLine(headersXML.Trim());
            DataSet dsCars = new DataSet("Cars");
            dsCars.Tables.Add(ds1.Tables[3].Copy());
            string carsXML = dsCars.GetXml();
            //    Console.WriteLine(carsXML);
            DataSet dsTrucks = new DataSet("Trucks");
            dsTrucks.Tables.Add(ds2.Tables[3].Copy());
            string trucksXML = dsTrucks.GetXml();
            //  Console.WriteLine(trucksXML);
            string resultXML = @"<document>"   headersXML   "<body>"   Environment.NewLine   carsXML   trucksXML   Environment.NewLine   "</body>"   Environment.NewLine   "</document>";
            Console.WriteLine(resultXML);


Your required XML
    <document>
      <header>
        <startDate>01/01/2020</startDate>
        <endDate> 01/02/ 2020</endDate>
      </header>
    <body>
    <Cars>
      <car>
        <ID>1</ID>
        <Name>Blue Car</Name>
      </car>
      <car>
        <ID>2</ID>
        <Name>Red Car</Name>
      </car>
    </Cars><Trucks>
      <truck>
        <ID> 1 </ID>
        <Name> Blue Truck </Name>
      </truck>
      <truck>
        <ID>2</ID>
        <Name>Red Truck</Name>
      </truck>
    </Trucks>
    </body>
    </document>

CodePudding user response:

Using xml linq :

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

namespace ConsoleApplication2
{
    class Program
    {
        const string FILE1 = @"c:\TEMP\TEST.XML";
        const string FILE2 = @"c:\TEMP\TEST1.XML";
        static void Main(string[] args)
        {
            string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><document></document>";
            XDocument doc3 = XDocument.Parse(xml);
            XElement doc = doc3.Root;
            doc.Add(new XElement("header", new XElement("Date", DateTime.Now.ToString("mm/dd/yyyy"))));

            XDocument doc1 = XDocument.Load(FILE1);
            XDocument doc2 = XDocument.Load(FILE2);

            XElement body = new XElement("body");
            doc.Add(body);

            XElement cars = new XElement("cars");
            doc.Add(cars);

            List<XElement> cars1 = doc1.Descendants("car").ToList();
            cars.Add(cars1);
            List<XElement> cars2 = doc2.Descendants("car").ToList();
            cars.Add(cars2);

            XElement trucks = new XElement("trucks");
            doc.Add(trucks);

            List<XElement> trucks1 = doc1.Descendants("truck").ToList();
            trucks.Add(trucks1);
            List<XElement> trucks2 = doc2.Descendants("truck").ToList();
            trucks.Add(trucks2);

        }
    }
}
  
  • Related