Search code examples
xmllinqxpath-1.0

LINQ/XML in C# - returning an XPATH count with XPathEvaluate


I'm trying to understand how to take any standard XPath from another tool, and make it work in C# with Linq. I know there many other ways to get the answer, but this is for specific research and learning that I'm doing.
I use XPath all the time, and seems like I should be able to copy it from any other tool using XPath 1.0 and run it here (like I can with XmlDocument and SelectSingleNode method). Actually, I haven't tried the Count with SelectSingleNode, will do that later this weekend.

First, I found that I have to use the XPathEvaluate on XDocument instead of XElement, so I don't have to remove the first part of the XPath.

using System;
using System.Xml.Linq;
using System.Xml.XPath; 

namespace Linq_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            XElement root = new XElement("Root",
                    new XElement("Child", "John"),
                    new XElement("Child", "Jane")
                );
            XDocument xdoc = new XDocument(root);
            /*
            XElement el = root.XPathSelectElement("./Child[1]");
            Console.WriteLine(el);
            */

            string xpathChildCount1 = "count(Root/Child)";
            string strChildCount1 =
                  xdoc.XPathEvaluate("string(" + xpathChildCount1 + ")") as string;
            Console.WriteLine("ChildCount1=" + strChildCount1);

            string strChildCount2 =
                  xdoc.XPathEvaluate(xpathChildCount1) as string;
            Console.WriteLine("ChildCount2=" + strChildCount2);

            /*
            int intChildCount = (int)root.XPathEvaluate("string(" + xpathChildCount + ")");
            Console.WriteLine("Numeric ChildCount=" + intChildCount);
            */


            Console.WriteLine("\n\n Press enter to end ....");
            Console.ReadLine();

        }
    }
}

To get the Count() to work, this StackOverflow post gave me the idea to wrap the XPath with "string(XPath)".

ChildCount1=2 
ChildCount2=

Is there a way to get back the count to an integer without having to wrap the "string()" around the XPath? Yes, I can cast the string to an integer, but why is it needed?


Solution

  • According to Microsoft Documentation XPathEvaluate, the method returns An object that can contain a bool, a double, a string, or an or IEnumerable, so you could use double instead string to get the Count like :

    double? nullableCount = root.XPathEvaluate(xpathChildCount1) as double?;
    double count = nullableCount.Value;
    Console.WriteLine("ChildCount2=" + count);
    

    Result

    ChildCount2=2
    

    I hope you find this helpful.