dotnet Exception Handling

.NET Exceptions – System.Xml.XPath.XPathException

Continuing our journey through the in-depth .NET Exception Handling series, today we’ll go over the System.Xml.XPath.XPathException. A XPathException is thrown anytime an error occurs while performing basic XPath parsing, using classes such as XPathNavigator and the like.

Throughout this article we’ll explore the XPathException in more detail, starting with where it sits in the .NET exception hierarchy. We’ll also look over some functional C# code samples that will show how we might typically try to parse an XML file using XPath expressions, and what might, therefore, cause a XPathException to occur, so let’s get going!

The Technical Rundown

All .NET exceptions are derived classes of the System.Exception base class, or derived from another inherited class therein. The full exception hierarchy of this error is:

Full Code Sample

Below is the full code sample we’ll be using in this article. It can be copied and pasted if you’d like to play with the code yourself and see how everything works.

When Should You Use It?

To see how a XPathException might be thrown, we first need to briefly review what XML Path Language (or XPath) is and how it works. In the simplest sense, XPath is an query language syntax used to select nodes in hierarchical XML documents. Since XML is an elemental, hierarchical format, XPath represents the relationships between nodes (or elements) using forward slashes (/), along with a number of special characters. thus, consider an XML document that looks like this:

With XPath, we could select nodes simply by indicating their element names, separated by a forward slash. Thus, the inner-most element could be selected with XPath of: //Base/First/Second

There’s far more to learn about XPath, so if you’re interested, the MDN Documentation is a solid place to start.

For our sample code today we’ll be trying to select nodes from a simple books.xml file:

Most of our code is found in the GetXPathNodesFromXml(string file, string xPath, XmlNamespaceManager manager = null) method:

All this method really does is creates an XPathDocument for the passed XML file, then we use a new navigator to select the node(s) using the passed xPath string and (optional) XmlNamespaceManager. All selected nodes are output to the log.

To test this out with our books.xml document we’ve defined a relatively basic XPath expression that selects the Title element text for each unique Book element:

Everything looks good, but executing this code immediately outputs a problem, in the form of a thrown XPathException:

Experienced XPathers may have noticed the issue before we even tried to run this code, but the problem here is that our XML structure uses an XML namespace of Airbrake, which precedes the parent Books element. Since the XmlNamespaceManager manager = null parameter of our method defaults to null, we didn’t pass a manager to the navigator.Select(...) method call, which is required in this situation where our XML document uses a namespace.

To resolve this, we’ve added a signature override that accepts namespace information:

As you can see, all we do here is add a new namespace to the XmlNamespaceManager instance, based on the passed @namespace name and namespaceUrl values, then we forward the rest of the execution onto our previous, baseline GetXPathNodesFromXml(string file, string xPath, XmlNamespaceManager manager = null) method signature. We can test this new method signature with the following code:

Now that we’ve added the required namespace, everything works as expected, selecting the Title nodes for each Book element and outputting the values:

Finally, just for fun, we can slightly modify our XPath expression, using the special asterisk (*) character, to select all child elements within each Book element:

The output shows that we’re able to get the value of each book’s child element collection, without needing to know the actual names of said child elements:

To get the most out of your own applications and to fully manage any and all .NET Exceptions, check out the Airbrake .NET Bug Handler, offering real-time alerts and instantaneous insight into what went wrong with your .NET code, along with built-in support for a variety of popular development integrations including: JIRA, GitHub, Bitbucket, and much more.