471,594 Members | 2,068 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,594 software developers and data experts.

How do you get the XPath expression of the current node?

Rob
Hi,

I am moving through an XML document using an XPath Navigator, and I'd
like to be able to get the xpath expression for the location of the
current node from the root node.

Any ideas how to do this? I was hoping for a property of the navigator
object, but I can't find it.....

Thanks in advance for any help!
Rob
Code sample:
private void Page_Load(object sender, System.EventArgs e)
{
XPathNavigator nav;
XPathDocument docNav;
docNav = new XPathDocument(@"c:\template.xml");
nav = docNav.CreateNavigator();
nav.MoveToRoot();
nav.MoveToFirstChild();

do
{
if (nav.NodeType == XPathNodeType.Element)
{
if (nav.HasChildren)
{
nav.MoveToFirstChild();
//what is the XPath expression for this node?
}
}
} while (nav.MoveToNext());
}
Nov 12 '05 #1
1 10609
Rob wrote:
I am moving through an XML document using an XPath Navigator, and I'd like
to be able to get the xpath expression for the location of the current
node from the root node.


I'm not aware of any toolset that provides that functionality, .NET
Framework or otherwise. I think that your question is under-specified: for
any given node in an XML instance document, there may be a very large number
of XPath expressions that all describe the node.

Consider the <c> element in this document:

<a>
<b/>
<b><c/></b>
<b><d/></b>
</a>

Here are a just few of the XPaths that describe it:

/a/b/c, //a/b/c, //b/c, //c, a/b/c[1], /a[1]/b[2]/child:*,
/a/b[d]/preceding-sibling::*/c, //d/ancestor::*[2]//c, /*[1]/*[2]/*[1], etc.

Some of these seem contrived, but each expresses a different relationship
among the nodes. The different relationships could indicate how an
XPathNavigator navigated to particular node.

So, restating the issue, there is no "the" XPath expression for the location
of a node.

When I had a similar need a while back, I created an XmlReader that that
kept track of the currently nested elements and position counts, and exposed
that through a property, so the "canonical" XPath in my custom XmlReader
would look like

/a[1]/b[2]/c[1]

It was not overly complex. This might help you get started.

public class XPathXmlReader : XmlReader
{
private XmlReader reader;

// this ctor allows XmlReaders to be chained
public XPathXmlReader( XmlReader reader ) { this.reader = reader; }

private Stack currentPath;
public string CurrentPath { get { /* ... */ } }

/*
implement all the XmlReader methods in terms of this.reader
and use the currentPath stack to keep track of where you are.
*/
}

Exposing a CurrentPath property for an XPathNavigator would require a
different approach. If performance expense were no object, you could wrap an
XPathNavigator inside of a custom XPathNavigator, and have the custom class
use a combination of methods like MoveToParent and MoveToPrevious (etc.) to
determine the path back to the root from the current node. you could do that
either on a Clone of the object, or navigate back to the current node
position. Obviously, neither of these scale well to large XML documents. You
might also leverage the SelectAncestors method.

Cheers,
Stuart Celarier, Fern Creek
Nov 12 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by gimme_this_gimme_that | last post: by
13 posts views Thread by David Thielen | last post: by
1 post views Thread by Sergey Dubinets | last post: by
7 posts views Thread by Tim Hallwyl | last post: by
reply views Thread by XIAOLAOHU | last post: by
reply views Thread by leo001 | last post: by
reply views Thread by Anwar ali | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.