/Patchers/Utilities.cs |
@@ -4,11 +4,9 @@ |
// rights of fair usage, the disclaimer and warranty conditions. // |
/////////////////////////////////////////////////////////////////////////// |
// Based on: https://seattlesoftware.wordpress.com/2009/03/13/get-the-xpath-to-an-xml-element-xelement/ |
|
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Text; |
using System.Reflection; |
using System.Xml.Linq; |
|
namespace wasStitchNET.Patchers |
@@ -15,14 +13,13 @@ |
{ |
public static class Utilities |
{ |
|
/// <summary> |
/// Get the absolute XPath to a given XElement |
/// (e.g. "/people/person[6]/name[1]/last[1]"). |
/// </summary> |
/// <param name="element"> |
/// The element to get the index of. |
/// </param> |
/// <summary> |
/// Get the absolute XPath to a given XElement |
/// (e.g. "/people/person[6]/name[1]/last[1]"). |
/// </summary> |
/// <param name="element"> |
/// The element to get the index of. |
/// </param> |
public static string GetAbsoluteXPath(this XElement element) |
{ |
if (element == null) |
@@ -35,40 +32,38 @@ |
|
// If the element is the root, no index is required |
|
return (index == -1) ? "/" + name : string.Format |
( |
"/{0}[{1}]", |
name, |
index.ToString() |
); |
return index == -1 |
? "/" + name |
: string.Format |
( |
"/{0}[{1}]", |
name, |
index.ToString() |
); |
}; |
|
var ancestors = from e in element.Ancestors() |
select relativeXPath(e); |
select relativeXPath(e); |
|
return string.Concat(ancestors.Reverse().ToArray()) + |
relativeXPath(element); |
} |
|
/// <summary> |
/// Get the index of the given XElement relative to its |
/// siblings with identical names. If the given element is |
/// the root, -1 is returned. |
/// </summary> |
/// <param name="element"> |
/// The element to get the index of. |
/// </param> |
/// <summary> |
/// Get the index of the given XElement relative to its |
/// siblings with identical names. If the given element is |
/// the root, -1 is returned. |
/// </summary> |
/// <param name="element"> |
/// The element to get the index of. |
/// </param> |
public static int IndexPosition(this XElement element) |
{ |
if (element == null) |
{ |
throw new ArgumentNullException("element"); |
} |
|
if (element.Parent == null) |
{ |
return -1; |
} |
|
var i = 1; // Indexes for nodes start at 1, not 0 |
|
@@ -75,9 +70,7 @@ |
foreach (var sibling in element.Parent.Elements(element.Name)) |
{ |
if (sibling == element) |
{ |
return i; |
} |
|
i++; |
} |
@@ -85,6 +78,5 @@ |
throw new InvalidOperationException |
("element has been removed from its parent."); |
} |
|
} |
} |
} |
/Patchers/XML.cs |
@@ -13,11 +13,34 @@ |
{ |
public static class XML |
{ |
public static XDocument PatchConfiguration(XDocument cfg, XDocument nfg, HashSet<string> configuredTags) |
public static HashSet<string> GetFileDelta(string cfg, string nfg) |
{ |
/*foreach (var e in nfg.Descendants() |
.Where(e => !configuredTags.Contains(e.Name.LocalName) && |
!e.Ancestors().Any(o => configuredTags.Contains(o.Name.LocalName))))*/ |
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))) |
{ |
@@ -34,16 +57,19 @@ |
// Element not found in the current configuration. |
default: |
// Find the first existing parent of the default configuration in the current configuration. |
var parent = e.Parent; |
XElement cfgParentElement = null; |
var parent = e; |
do |
{ |
cfgParentElement = cfg.XPathSelectElement(parent.GetAbsoluteXPath()); |
parent = e.Parent; |
} while (cfgParentElement == null); |
|
// Add the default configuration parent to the current configuration. |
cfgParentElement = nfg.XPathSelectElement(cfgParentElement.GetAbsoluteXPath()); |
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; |
} |
} |
@@ -50,9 +76,4 @@ |
return cfg; |
} |
} |
} |
|
|
|
|
|
} |