Comparing two xml files, adding missing elements

This raises a difficult question.

I have one MainFile.XML file that looks like this:

<xml>
  <header>
     <some></some>
     <addThis></addThis>
  </header>
  <footer></footer>
  <this>
    <is>
      <deep>
        <like></like>
     </deep>
   </is>
  </this>
<test></test>
<page></page>
<addThis></addThis>

And my other LangFile.XML file looks like this.

<xml>
  <header>
    <some>English file</some>
  </header>
  <footer>Footer</footer>
  <this>
    <is>
      <deep>
        <like>Hey</like>
      </deep>
    </is>
  </this>
  <test>Something</test>
</xml>

I want to update my LangFile.XML so that it matches my MainFile.XML file, but I need to save all the Text values ​​in the LangFile.

I want the LangFile to look like this after the update: EXPECTED EXIT

<xml>
  <header>
    <some>English file</some>
    <addThis></addThis>
  </header>
  <footer>Footer</footer>
  <this>
  <is>
    <deep>
      <like>Hey</like>
    </deep>
  </is>
  </this>
  <test>Something</test>
  <page></page>
  <addThis></addThis>
</xml>

I looked at this answer, but I need to update the file and save the values ​​... Comparing two text files line by line

The hard part is investing, it can be anything between levels from level 1 to X ...

, , , , - , ... , .

String directory = @"C:\Utv\XmlTest";

var mainFile = XDocument.Load(Path.Combine(directory, "MainFile.XML"));
var langFile = XDocument.Load(Path.Combine(directory, "LangFile.XML"));

//Get all descendant nodes
var mainFileDesc = mainFile.Root.Descendants().ToList();
var langFileDesc = langFile.Root.Descendants().ToList();

//Loop through the mainfile
for(var i = 0; i < mainFileDesc.Count(); i++)
{
    var mainRow = mainFileDesc[i];
    var langRow = langFileDesc[i];

    //Compare the rows descendants, if not the same, add the mainRow to the langRow
    if(mainRow.Descendants().Count() != langRow.Descendants().Count())
    {
        //Here I want to check if the mainRow != the langRow
                    //if not, add the mainRow to the langFile list
                    if(mainRow != langRow)
                    {
                      langFileDesc.Insert(i, mainRow);
                    }
    }
}

:

var langRow = langFileDesc[i];
Message Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index 

, , ...

+4
2

, xml XML , , . , xpath, :

   private static void Main(string[] args)
    {
        try
        {
            XmlDocument xml1 = new XmlDocument();
            xml1.Load(@"C:\testxml\MainFile.xml");
            XPathNavigator nav = xml1.CreateNavigator();

            //Create the langFile Navigator
            XPathDocument xml2 = new XPathDocument(@"C:\testxml\LangFile.xml");
            XPathNavigator nav2 = xml2.CreateNavigator();
            //Select all text nodes.
            var nodes = nav2.SelectDescendants(XPathNodeType.Text, true);
            while (nodes.MoveNext())
            {
                //Update the MainFile with the values in the LangFile

                var c = nav.SelectSingleNode(GetPath(nodes.Clone().Current));//(1*)
                if(c != null)
                {
                    c.MoveToFirstChild();
                    c.SetValue(nodes.Current.Value);
                }
            }
            Console.WriteLine(xml1.InnerXml);
            Console.ReadKey();
        }
        catch
        {
        }
    }
    private static string GetPath(XPathNavigator navigator)
    {
        string aux =string.Empty;
        while (navigator.MoveToParent())
        {
            aux = navigator.Name + "/"+aux;
        }
        return "/" + (aux.EndsWith("/")?aux.Remove(aux.LastIndexOf('/')):aux);
    }

, , xml node , (* 1) . , .

+2

, . , - , .

, , . , , . , , .

/// <summary>
/// Copy A to B where B doesn't have A nodes.
/// </summary>
public static void EvenUp(XElement A, XElement B)
{
    XNode lastB = null, nodeA = null, nodeB = null;

    Action Copy_A_To_B = () =>
    {
        if (null == lastB)
            B.AddFirst(nodeA);
        else
            lastB.AddAfterSelf(nodeA);
    };

    var listA = A.Nodes().ToList();
    var listB = B.Nodes().ToList();
    int a, b;

    for (a = 0, b = 0; a < listA.Count && b < listB.Count; a++, b++)
    {
        nodeA = listA[a];
        nodeB = listB[b];

        XElement xA = nodeA as XElement,
            xB = nodeB as XElement;

        XText tA = nodeA as XText,
            tB = nodeB as XText;

        if (null != xA && null != xB)
        {
            if (xA.Name.LocalName == xB.Name.LocalName)
                EvenUp(xA, xB);
            else
            {
                Copy_A_To_B();
                EvenUp(A, B); // Restart this iteration for various reasons such as 
                                // the next nodeA might be the same as current nodeB
                return;
            }
        }
        else if (null != xA)
            Copy_A_To_B();
        else if (null != tA && null != tB)
        {
            if (tA.Value != tB.Value)
                tB.Value = tA.Value;
        }
        else if (null != tA)
            Copy_A_To_B();

        lastB = nodeB;
    }
    for (; a < listA.Count; a++)
    {
        nodeA = listA[a];
        Copy_A_To_B();
        if (null == lastB)
            lastB = B.FirstNode;
        else
            lastB = lastB.NextNode;
    }
}

:

XElement mainFile = XElement.Load("xmlfile1.xml");
XElement langFile = XElement.Load("xmlfile2.xml");

EvenUp(mainFile, langFile);

Console.WriteLine(langFile.ToString());
Console.ReadLine();

, , : EvenUp(langFile, mainFile) .

+2

All Articles