wasStitchNET – Rev 8

Subversion Repositories:
Rev:
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2017 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////

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

namespace wasStitchNET.Patchers
{
    public static class XML
    {
        public static HashSet<string> GetFileDelta(string cfg, string nfg)
        {
            var configuredTags = new HashSet<string>();

            var configuration = XDocument.Load(cfg);
            foreach (var e in XDocument.Load(nfg).Descendants())
            {
                var cfgElement = configuration.XPathSelectElement(e.GetAbsoluteXPath());
                if (cfgElement == null)
                {
                    configuredTags.Add(e.Name.LocalName);
                    continue;
                }

                if (e.Descendants().Any())
                    continue;

                if (!cfgElement.Value.Equals(e.Value))
                    continue;

                configuredTags.Add(e.Name.LocalName);
            }

            return configuredTags;
        }

        public static XDocument PatchXDocument(XDocument cfg, XDocument nfg, HashSet<string> configuredTags)
        {
            foreach (var e in nfg.Descendants()
                .Where(e => configuredTags.Contains(e.Name.LocalName)))
            {
                // Select the element in the current configuration that is found in the default configuration.
                var cfgElement = cfg.XPathSelectElement(e.GetAbsoluteXPath());
                switch (cfgElement != null)
                {
                    // Element found in current configuration.
                    case true:
                        // Only set the element value if it has no descendants.
                        if (!cfgElement.Descendants().Any())
                            cfgElement.Value = e.Value;
                        break;
                    // Element not found in the current configuration.
                    default:
                        // Find the first existing parent of the default configuration in the current configuration.
                        var parent = e;
                        do
                        {
                            var cfgParentElement = cfg.XPathSelectElement(parent.GetAbsoluteXPath());
                            if (cfgParentElement != null)
                            {
                                // Add the default configuration parent to the current configuration.
                                cfgParentElement.ReplaceWith(
                                    nfg.XPathSelectElement(cfgParentElement.GetAbsoluteXPath()));
                                break;
                            }
                            parent = parent.Parent;
                        } while (parent != null);
                        break;
                }
            }
            return cfg;
        }
    }
}

Generated by GNU Enscript 1.6.5.90.