When I load a XML-Document from a file, and then get an XmlNode from it, is
there any way to get the its original position in the file (line,
character)?
I want to report it, when there is something odd about that node, so that a
user can find the position in the file. Similar to the errormessage from
XmlDocument.Load, if the file isn't wellformed XML.
If that's not possible, would it be possible when examining the XML with
other technics?
thanks
Christof
Even if it were a trivial process to extract the position of the node
within the text you'd have to deal with environments "pretty printing"
the XML. They all seem to do it differently and you can't garauntee
that any one will or will not insert spaces over tabs and place
carriage returns exactly where you believe they should be. There is
no (and there should be no) relationship between the file and the DOM.
One way you may consider doing it is to produce an xpath based on the
node in error and the user can enter that into their specific viewer
to locate it. Unless of course they use a flat text reader. But
applications like Altova XmlSpy ($$) and Doxygen (free as in beer)
will accept an xpath and reliably navigate the document for you.
public string GetXPath(XmlNode child, XmlNode parent)
{
// this will hold our xpath
StringBuilder path = new StringBuilder();
// climb the nodes from the incoming node 'n' upto the root
for (XmlNode p = child; p != parent && p.ParentNode != null; p =
p.ParentNode)
{
// get the element index by counting the previous siblings
int sibCount = 1;
for (XmlNode pn = p.PreviousSibling;
pn != null;
pn = pn.PreviousSibling, ++sibCount) ;
// prepend it to our xpath
path.Insert(0, "/node()[" + sibCount + "]");
}
//Prepend this for the document root.
path.Insert(0, "/node()[1]");
// and return the completed xpath to the incoming node
return path.ToString();
}
You can use the above method to generate an xpath for a specific node
upto a specific parent. Another version of this would automatically
default the parent to the root of the document if that's all you
needed.
Hope this helps,
John