tags:

views:

211

answers:

3

We would like to implement existance checks of elements via XPath expression. The XPath expressions are defined externally. We are trying to use the XPathEvaluate extension method from System.Xml.XPath, but it complains when we try to do the following.

XDocument d = new XDocument(
                new XElement("test", 
                    new XElement("element"),
                    new XElement("element")));
bool b = (bool)d.XPathEvaluate("/test/element[exists()]");

This function currently fails with an exception "Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.". We get the same message if we try exists(/test/element).

One of the other things that we would like to express in an XPath expression is the number of elements, e.g. count(/text/element) = 2.

The testing condition should be part of the XPath expression.

The function call d.XPathEvaluate("/test/element[last()]") evaluates as expected.

Is it possible to use XPathEvaluate this way?

[Edit] Yes.

If not, are there any alternatives in the .Net framework?

[Edit] Yes.

[Edit] Remaining question: why doesn't the exists function work?

+1  A: 

After some more experimenting, it seems like I answered my own question.

Of course you can do count(/test/element) > 0 as an exists check. (And we were looking at this with three people :-( )

bool b = (bool)d.XPathEvaluate("count(/test/element) > 0");
Jeroen Huinink
+1  A: 

Have you tried the XPath:

boolean(/test/element)
santiiiii
Not before, but just tested it and it works.
Jeroen Huinink
A: 

Remaining question: why doesn't the exists function work?

You are calling the exists() function incorrectly. The exists() function needs at least one argument.

Rather than using it in a predicate for your XPATH expression, use the XPATH expression as the parameter for the exists() function.

bool b = (bool)d.XPathEvaluate("exists(/test/element)");
Mads Hansen
We already tried that with the same result. It's noted in my question.
Jeroen Huinink