wasStitchNET – Rev 8
?pathlinks?
///////////////////////////////////////////////////////////////////////////
// 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. //
///////////////////////////////////////////////////////////////////////////
// Based on: https://seattlesoftware.wordpress.com/2009/03/13/get-the-xpath-to-an-xml-element-xelement/
using System;
using System.Linq;
using System.Xml.Linq;
namespace wasStitchNET.Patchers
{
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>
public static string GetAbsoluteXPath(this XElement element)
{
if (element == null)
throw new ArgumentNullException("element");
Func<XElement, string> relativeXPath = e =>
{
var index = e.IndexPosition();
var name = e.Name.LocalName;
// If the element is the root, no index is required
return index == -1
? "/" + name
: string.Format
(
"/{0}[{1}]",
name,
index.ToString()
);
};
var ancestors = from e in element.Ancestors()
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>
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
foreach (var sibling in element.Parent.Elements(element.Name))
{
if (sibling == element)
return i;
i++;
}
throw new InvalidOperationException
("element has been removed from its parent.");
}
}
}
Generated by GNU Enscript 1.6.5.90.