简体   繁体   中英

How to merge one specific tag into one XML using c#?

I have two XMLs'

XML1:

'<?xml version="1.0" encoding="utf-8"?>
    <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
         <Filename>1234</Filename>
             <Sequence Type="FRONT">
                <Object>
                    <Value>3421</Value>
                    <Value>John</Value>
                </Object>
             </Sequence>
      </Data>'

XML2:

 '<?xml version="1.0" encoding="utf-8"?>
    <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
         <Filename>1234</Filename>
             <Sequence Type="FRONT">
                <Object>
                    <Value>1234</Value>
                    <Value>SAM</Value>
                </Object>
             </Sequence>
      </Data>'

I want the output like below

 '<?xml version="1.0" encoding="utf-8"?>
    <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
         <Filename>1234</Filename>
             <Sequence Type="FRONT">
                <Object>
                    <Value>3421</Value>
                    <Value>John</Value>
                </Object>
                <Object>
                    <Value>1234</Value>
                    <Value>SAM</Value>
                </Object>
             </Sequence>
      </Data>'

Ie I want to merge Object tag from XML2 to XML1 using C# code.

Could someone please help me?

You can use XPath to select the nodes you need and then simply use .NET xml using System.Xml

For more information look at https://www.w3schools.com/xml/xpath_intro.asp

Load Xml Documents

I saved the two sample xml-files you provided to separate files and imported them like this XmlDocument doc1 = new XmlDocument(); XmlDocument doc2 = new XmlDocument();

    using (var sw = new StreamReader("xml1.xml"))
    {
        var text = sw.ReadToEnd();
        doc1.LoadXml(text);
    }

    using (var sw = new StreamReader("xml2.xml"))
    {
        var text = sw.ReadToEnd();
        doc2.LoadXml(text);
    }

Select nodes with XPATH

We will take all elements that have the name 'object' and add them to child of the other xml's 'sequence'-element. Therefore we select the 'sequence'-element of one document and the 'object'elements of the other document.

    var sequenceNodes = doc1.SelectSingleNode("/Data/Sequence");
    var objectNodes = doc2.SelectNodes("/Data/Sequence/Object");

Concat the nodes into one document

Then we take each 'object'-element, import it into the other document-context and append it under the 'sequence'-node

    foreach (XmlNode node in objectNodes)
    {
        XmlNode importedNode = doc1.ImportNode(node, true);
        sequenceNodes.AppendChild(importedNode);
    }

Output the file

    using (var stringWriter = new StringWriter())
    using (var xmlTextWriter = XmlWriter.Create(stringWriter))
    {
        doc1.WriteTo(xmlTextWriter);
        xmlTextWriter.Flush();
        File.AppendAllText("out.xml", stringWriter.GetStringBuilder().ToString());
    }

The outputfile looks like this: 在此处输入图片说明

Please, take a look at this solution: what-is-the-fastest-way-to-combine-two-xml-files-into-one

Using Union method seems to be what you are seeking.

Run an XSLT transformation:

<xsl:template name="merge">
   <Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
         <Filename>1234</Filename>
         <Sequence Type="FRONT">
                <xsl:copy-of select="document('a.xml')//Object"/>
                <xsl:copy-of select="document('b.xml')//Object"/>
         </Sequence>
   </Data>
</xsl:template>  

Try following linq which joins all filenames with same value.

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

namespace ConsoleApplication166
{
    class Program
    {
        const string FILENAME1 = @"c:\temp\test.xml";
        const string FILENAME2 = @"c:\temp\test1.xml";
        static void Main(string[] args)
        {
            XDocument doc1 = XDocument.Load(FILENAME1);
            XNamespace ns1 = doc1.Root.GetDefaultNamespace();
            XDocument doc2 = XDocument.Load(FILENAME2);
            XNamespace ns2 = doc2.Root.GetDefaultNamespace();

            var joins= from d1 in doc1.Descendants(ns1 + "Data")
                       join d2 in doc2.Descendants(ns2 + "Data")
                       on (string)d1.Element(ns1 + "Filename") equals (string)d2.Element(ns2 + "Filename")
                       select new { d1 = d1, d2 = d2};

            foreach (var join in joins)
            {
                XElement d2Object = join.d2.Descendants("Object").FirstOrDefault(); 
                join.d1.Descendants("Sequence").FirstOrDefault().Add(XElement.Parse(d2Object.ToString()));
            }


        }
    }
 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM