How to get line numbers when evaluating XPath-expressions?

L

linuxadmin

Hello everyone!

I evaluate XPath expressions using XPathNavigator and need to know for
each result, which line number (or et least file position) it has
inside the XML file.

Any ideas?

Thanks in advice!
 
L

linuxadmin

Hello!

Isn't it possible to "locate" an XPathNavigator (XPathNode?) after it
was returned, using XmlReader or something else?
 
G

Guest

Yes, it is possible but quite involved.

Your task is a lot easier if you know that each element, comment &
processing instruction starts on a new line and that there are no empty
lines. If this isn't the case you may want to create your own version of the
XML file first, preserving whitespace is an issue here though.

XmlReader can be used but it does not return its location within the file,
so you will need to keep track of this yourself, or you may want to use
TextReader with regular expressions.

The key thing you need is the ordinal position of the element immediately
preceding the returned node from the expression (this helps cover the case
when a node returned is a mixed-content text node) using an xpath expression.

SketchPath is an example XPath application that uses this technique on its
own representation of the XML file.

The following rough code snippet (from SketchPath) might give your some
ideas, this is incomplete, only caters for element nodes and doesn't take
account of comments and processing-instructions.


XPathExpression expr = xnav.Compile(contextXpath);
expr.SetContext(namespaceData);
if (expr.ReturnType == XPathResultType.NodeSet)
{
XPathNodeIterator iterator =
(XPathNodeIterator)xnav.Evaluate(expr);
iterator.MoveNext();
if (iterator.Current.NodeType == XPathNodeType.Element)
{
xnav = (XPathNavigator)iterator.Current.Clone(); //
preserve location of context element in navigator

// find number of preceding elements
double elCount =
(double)xnav.Evaluate("count(./preceding::*) + count(./ancestor::*)");
....

Phil Fearon
http://www.sketchpath.com
 
L

linuxadmin

Thanks a lot!
I'll try it out




Yes, it is possible but quite involved.

Your task is a lot easier if you know that each element, comment &
processing instruction starts on a new line and that there are no empty
lines. If this isn't the case you may want to create your own version of the
XML file first, preserving whitespace is an issue here though.

XmlReader can be used but it does not return its location within the file,
so you will need to keep track of this yourself, or you may want to use
TextReader with regular expressions.

The key thing you need is the ordinal position of the element immediately
preceding the returned node from the expression (this helps cover the case
when a node returned is a mixed-content text node) using an xpath expression.

SketchPath is an example XPath application that uses this technique on its
own representation of the XML file.

The following rough code snippet (from SketchPath) might give your some
ideas, this is incomplete, only caters for element nodes and doesn't take
account of comments and processing-instructions.

XPathExpression expr = xnav.Compile(contextXpath);
expr.SetContext(namespaceData);
if (expr.ReturnType == XPathResultType.NodeSet)
{
XPathNodeIterator iterator =
(XPathNodeIterator)xnav.Evaluate(expr);
iterator.MoveNext();
if (iterator.Current.NodeType == XPathNodeType.Element)
{
xnav = (XPathNavigator)iterator.Current.Clone(); //
preserve location of context element in navigator

// find number of preceding elements
double elCount =
(double)xnav.Evaluate("count(./preceding::*) + count(./ancestor::*)");
....

Phil Fearonhttp://www.sketchpath.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top