Skip to content

Instantly share code, notes, and snippets.

@virtualstaticvoid
Created January 24, 2011 09:55
Show Gist options
  • Save virtualstaticvoid/793023 to your computer and use it in GitHub Desktop.
Save virtualstaticvoid/793023 to your computer and use it in GitHub Desktop.
Utility for determining the XPath of a given node
using System;
using System.Text;
using System.Xml;
using System.Xml.XPath;
public static class XPathHelp
{
public static string GetXPathForNode(XmlNode node)
{
return GetXPathForNode(node.CreateNavigator());
}
public static string GetXPathForNode(XPathNavigator node)
{
StringBuilder sb = new StringBuilder();
BuildNodeXPath(node, sb);
return sb.ToString();
}
private static void BuildNodeXPath(XPathNavigator node, StringBuilder sb)
{
if (node.NodeType == XPathNodeType.Root)
{
sb.Append("/");
return;
}
XPathNavigator treeWalk = node.Clone();
if (treeWalk.MoveToParent())
{
if (treeWalk.NodeType != XPathNodeType.Root)
BuildNodeXPath(treeWalk, sb);
}
sb.AppendFormat("/{0}", XPathNodeName(node));
XPathNavigator nodeParent = node.Clone();
nodeParent.MoveToParent();
XPathNodeIterator siblings = node.NodeType == XPathNodeType.Element
? nodeParent.SelectChildren(node.LocalName, node.NamespaceURI)
: nodeParent.SelectChildren(node.NodeType);
if (siblings.Count < 2) return;
do
{
if (siblings.Current.ComparePosition(node) != XmlNodeOrder.Same) continue;
sb.AppendFormat("[{0}]", siblings.CurrentPosition);
break;
} while (siblings.MoveNext());
}
public static string XPathNodeName(XmlNode node)
{
return XPathNodeName(node.CreateNavigator());
}
public static string XPathNodeName(XPathNavigator node)
{
switch (node.NodeType)
{
case XPathNodeType.Attribute:
return String.Format("@{0}", node.Name);
case XPathNodeType.Comment:
return "comment()";
case XPathNodeType.Element:
return node.Name;
case XPathNodeType.Namespace:
return String.Format("namespace::{0}", node.Name);
case XPathNodeType.ProcessingInstruction:
return String.Format("processing-instruction(\"{0}\")", node.Name);
case XPathNodeType.Text:
return "text()";
default:
System.Diagnostics.Debugger.Break();
return String.Format("{{{0}}}", node.NodeType);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment