string BuildFeaturePath (XmlNode parent, XmlNode child) { if (parent == null) return "/"; List path = new List (); XmlNode cur = parent, last = null; while (cur != null && cur.NodeType != XmlNodeType.Document) { if (cur.NodeType == XmlNodeType.Element && cur.Name != Helpers.FakeRootName) path.Insert (0, cur.Name); last = cur; cur = cur.ParentNode; } string attributes = null; if (child != null && last.Name != child.Name) { if (child.NodeType == XmlNodeType.Element) path.Add (child.Name); attributes = BuildXPathFromAttributes (child); } else if (last != null) attributes = BuildXPathFromAttributes (last); path [path.Count - 1] += attributes; path.Insert (0, "/"); return String.Join ("/", path.ToArray ()); } string BuildXPathFromAttributes (XmlNode node) { XmlAttributeCollection attrs = node.Attributes; StringBuilder sb = new StringBuilder (); string and = String.Empty; bool first = true; foreach (XmlAttribute attr in attrs) { sb.AppendFormat ("{0}@{1}=\"{2}\"", and, attr.Name, attr.Value); if (first) { first = false; and = " and "; } } if (sb.Length == 0) return String.Empty; sb.Insert (0, "["); sb.Append ("]"); return sb.ToString (); }