I am trying to select values from elements using the XPathNodeIterator. But I am not able to get the expected value from my XML file.
My XML file
<?xml version="1.0" encoding="utf-8"?>
<ns0:Entity xmlns:ns0="http://schemas.mycompany.com/1.0">
<ns0:Data>
<Address_Id xmlns:ns0="http://schemas.mycompany.com/1.0">7</Address_Id>
<Customer_Id xmlns:ns0="http://schemas.mycompany.com/1.0">67</Customer_Id>
<CustomerName xmlns:ns0="http://schemas.mycompany.com/1.0">My Customer 1</CustomerName>
</ns0:Data>
</ns0:Entity>
My methods to get the values
I have created two methods which both doesn't return the values which I would like to have.
private static string GetValue_Attempt1(XPathDocument xPathDocument, string xpathExpression)
{
var xpathNavigator = xPathDocument.CreateNavigator();
var xpathNodeIterator = xpathNavigator.Select(xpathExpression);
xpathNodeIterator.MoveNext();
return xpathNodeIterator.Current.Value;
}
private static string GetValue_Attempt2(XPathDocument xPathDocument, string xpathExpression)
{
var xpathNavigator = xPathDocument.CreateNavigator();
var xpathNodeIterator = xpathNavigator.Select(xpathExpression);
xpathNodeIterator.MoveNext();
var nodesNavigator = xpathNodeIterator.Current;
var nodesText = nodesNavigator.SelectDescendants(XPathNodeType.Text, false);
nodesText.MoveNext();
return nodesText.Current.Value;
}
My XPath
//Data/Address_Id/text()767My Customer 1. Why are all values concatenated ???7. Looks OK//Data/Customer_Id/text()767My Customer 1. Why are all values concatenated ???7. Why do I get the Address_Id??Questions
Probably I am using an incorrect XPath. But also I don't understand the results. In order to understand whats going on. I would like to know:
GetValue_Attempt1 return a concatinated string?GetValue_Attempt2 return the value of only the first element?Your XPath returns no matches as you're not taking the namespaces into account.
Your 'Attempt 1' calls MoveNext() once, so Value returns all the concatenated text in Data, and in 'Attempt 2' you call MoveNext() twice which positions you inside the Address_Id element.
In addition, Select, even it the XPath was valid, doesn't actually move the cursor.
If you wanted to get the value, you'd do something like this - note I'm including the namespace in the XPath and using the result of SelectSingleNode:
var nsm = new XmlNamespaceManager(new NameTable());
nsm.AddNamespace("ns0", "http://schemas.mycompany.com/1.0");
var value = navigator.SelectSingleNode("//ns0:Data/Address_Id", nsm).Value;
However, do you have any reason to be using XPath and XPathDocument here? Using the much more expressive and (more) statically typed LINQ to XML would be far preferable, I'd think:
XNamespace ns = "http://schemas.mycompany.com/1.0";
var doc = XDocument.Parse(xml);
var addressId = (int)doc.Descendants(ns + "Data")
.Elements("Address_Id")
.Single();
var customerId = (int)doc.Descendants(ns + "Data")
.Elements("Customer_Id")
.Single();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With