Brian J. Hakim
Brian J. Hakim

Reputation: 993

XPathEvaluate does not evaluate a valid XPath

Sample xml:

<pr:InquiredPersonCode xmlns:pr="http://some/XMLSchemas/PR/v1-0" xmlns:epcs="http://some/XMLSchemas/EP/v1-0">
  <pr:PersonCode>111</pr:PersonCode>
  <pr:EServiceInstance>
      <epcs:TransactionID>Tran-1</epcs:TransactionID>
  </pr:EServiceInstance>
</pr:InquiredPersonCode>

And valid and well-formed XPath:

/*[local-name()='InquiredPersonCode' and namespace-uri()='http://some/XMLSchemas/PR/v1-0']/*[local-name()='EServiceInstance' and namespace-uri()='http://some/XMLSchemas/PR/v1-0']/*[local-name()='TransactionID' and namespace-uri()='http://some/XMLSchemas/EP/v1-0']

Then in code:

var values = message.XPathEvaluate(xPath);

Result is empty.

Upvotes: 1

Views: 1261

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167561

Brian, which XPath API are you using? When I used the System.Xml SelectNodes method or the LINQ extension method XPathEvaluate against your file it finds an element. Here is a sample:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace ConsoleApplication45
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = "/*[local-name()='InquiredPersonCode' and namespace-uri()='http://some/XMLSchemas/PR/v1-0']/*[local-name()='EServiceInstance' and namespace-uri()='http://some/XMLSchemas/PR/v1-0']/*[local-name()='TransactionID' and namespace-uri()='http://some/XMLSchemas/EP/v1-0']";

            XmlDocument doc = new XmlDocument();
            doc.Load("../../XMLFile1.xml");

            foreach (XmlElement el in doc.SelectNodes(path))
            {
                Console.WriteLine("Element named \"{0}\" has contents \"{1}\".", el.Name, el.InnerText);
            }

            Console.WriteLine();

            XDocument xDoc = XDocument.Load("../../XMLFile1.xml");

            foreach (XElement el in (IEnumerable)xDoc.XPathEvaluate(path))
            {
                Console.WriteLine("Element named \"{0}\" has contents \"{1}\".", el.Name.LocalName, el.Value);
            }
        }
    }
}

Output is

Element named "epcs:TransactionID" has contents "Tran-1".

Element named "TransactionID" has contents "Tran-1".

I wouldn't use XPathEvaluate to select elements, XPathSelectElements is easier to use. And I agree with comments made to use the namespaces, you can simply do

   XDocument xDoc = XDocument.Load("../../XMLFile1.xml");


    foreach (XElement id in xDoc.XPathSelectElements("pr:InquiredPersonCode/pr:EServiceInstance/epcs:TransactionID", xDoc.Root.CreateNavigator()))
    {
        Console.WriteLine("Found id {0}.", id.Value);
    }

Upvotes: 2

Related Questions