Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception: The XPath expression evaluated to unexpected type System.Xml.Linq.XAttribute

I've an XML file like below:

<Employees>
  <Employee Id="ABC001">
    <Name>Prasad 1</Name>
    <Mobile>9986730630</Mobile>
    <Address Type="Perminant">
      <City>City1</City>
      <Country>India</Country>
    </Address>
    <Address Type="Temporary">
      <City>City2</City>
      <Country>India</Country>
    </Address>
  </Employee>

Now I want get all Address Type's.

I tried like below using XPath and I'm getting exception.

var xPathString = @"//Employee/Address/@Type";
doc.XPathSelectElements(xPathString); // doc is XDocument.Load("xml file Path")

Exception: The XPath expression evaluated to unexpected type System.Xml.Linq.XAttribute.

Is there any issue with my XPath?

like image 920
Prasad Kanaparthi Avatar asked Sep 07 '16 02:09

Prasad Kanaparthi


3 Answers

Your XPath is fine (although you might want it to be more selective), but you have to adjust how you evaluate it...

XPathSelectElement(), as its name implies, should only be used to select elements.

XPathEvaluate() is more general and can be used for attributes. You can enumerate over the results, or grab the first:

var type = ((IEnumerable<object>)doc.XPathEvaluate("//Employee/Address/@Type"))
                                    .OfType<XAttribute>()
                                    .Single()
                                    .Value;
like image 121
kjhughes Avatar answered Nov 16 '22 02:11

kjhughes


Another option would be:

var addresses = doc.XPathSelectElements("//Employee/Address"));
foreach(var address in addresses) {
    var addrType = address.Attribute("Type").Value;
}
like image 23
knocte Avatar answered Nov 16 '22 02:11

knocte


Expanding on kjhughes's answer, I've tended to create an XElement class extension for this so that I can simply call element.XPathSelectAttribute(), which makes my calling code look a great deal clearner.

public static class XElementExtensions
{
    public static XAttribute XPathSelectAttribute(this XElement element, string xPath)
    {
        return ((IEnumerable<object>)element.XPathEvaluate(xPath)).OfType<XAttribute>().First();
    }
}
like image 1
Benj Avatar answered Nov 16 '22 04:11

Benj