Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way test for XPath existence in an XML file?

Tags:

c#

xml

Lately I've been using XPathDocument and XNavigator to parse an XML file for a given XPath and attribute. It's been working very well, when I know in advance what the XPath is.

Sometimes though, the XPath will be one of several possible XPath values, and I'd like to be able to test whether or not a given XPath exists.

In case I'm getting the nomenclature wrong, here's what I'm calling an XPath - given this XML blob:

<foo>
    <bar baz="This is the value of the attribute named baz">
</foo>

I might be looking for what I'm calling an XPath of "//foo/bar" and then reading the attribute "baz" to get the value.

Example of the code that I use to do this:

XPathDocument document = new XPathDocument(filename);
XPathNavigator navigator = document.CreateNavigator();
XPathNavigator node = navigator.SelectSingleNode("//foo/bar");
if(node.HasAttributes)
{
    Console.WriteLine(node.GetAttribute("baz", string.Empty));
}

Now, if the call to navigator.SelectSingleNode fails, it will return a NullReferenceException or an XPathException. I can catch both of those and refactor the above into a test to see whether or not a given XPath returns an exception, but I was wondering whether there was a better way?

I didn't see anything obvious in the Intellisense. XPathNavigator has .HasAttributes and .HasChildren but short of iterating through the path one node at a time, I don't see anything nicer to use.

like image 448
Mark Allen Avatar asked Oct 28 '08 22:10

Mark Allen


People also ask

How do I check if an element exists in XML?

To verify if node or tag exists in XML content, you can execute an xpath expression against DOM document for that XML and count the matching nodes. matching nodes > zero – XML tag / attribute exists. matching nodes <= zero – XML tag / attribute does not exist.

How do you check if an element exists in the XML using XPath?

Use the fn:nilled XPath function to test whether the value of an input element has the xsi:nil attribute set. Use the fn:exists XPath function to test whether the value of an input element is present. Note: An XML element that has the xsi:nil attribute set is considered to be present.


3 Answers

If you've given valid XPath but it doesn't match anything, SelectSingleNode won't throw a NullReferenceException - it will just return null.

If you pass SelectSingleNode some syntactically invalid XPath, that's when it will throw an XPathException.

So normally, you'd just need to test whether the returned value was null or not.

like image 81
Jon Skeet Avatar answered Sep 28 '22 19:09

Jon Skeet


 var baz = navigator.SelectSingleNode("//foo/bar/@baz");
 if (baz != null) Console.WriteLine(baz);
like image 28
Mark Cidade Avatar answered Sep 28 '22 17:09

Mark Cidade


I think it is not good to create an XMLNode object by executing navigator.SelectSingleNode(...).

You have to use navigator.Evaluate() instead:

if (Convert.ToBoolean(navigator.Evaluate(@"boolean(//foo/bar)"))) {...}
like image 34
Ron Avatar answered Sep 28 '22 17:09

Ron