I'm trying to get the inner text from a node after loading the XML file. I have tried this code with another file and it worked. But here I can't get the node values. Can anyone point out what am I doing wrong?
XML file - restaurant_reviews.xml
<?xml version="1.0"?> <restaurants xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.algonquincollege.com/onlineservice/reviews"> <restaurant> <name>Laughing Man</name> <logo> <name>Visit the Laughing Man</name> <imagefile>laughing-man.gif</imagefile> <width unit="px">50</width> <height unit="px">200</height> </logo> </restaurant> <restaurant> <name>Gong’s Asian Cuisine</name> <logo> <name/> <imagefile>gong-asian-cuisine.gif</imagefile> <width unit="px">150</width> <height unit="px">250</height> </logo> </restaurant> </restaurants>
C# Code
List<string> names = new List<string>();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(HttpContext.Current.Server.MapPath(@"~/App_Data/restaurant_reviews.xml"));
XmlNodeList nodes = xmlDoc.SelectNodes("/restaurants/restaurant");
foreach (XmlNode itemNode in nodes)
{
XmlNode titleNode = itemNode.SelectSingleNode("name");
if (titleNode != null)
{
names.Add(titleNode.InnerText);
}
}
Whilst this question already has an accepted answer, I wanted to add this anyway, as removing namespaces and manipulating XML in this way doesn't feel right to me, it was added for a reason I suspect.
What I believe is the correct approach is too add an XML Namespace Manager to your XPath query.
var nsMgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsMgr.AddNamespace("r", "http://www.algonquincollege.com/onlineservice/reviews");
Then in your SelectNodes and SelectSingleNodes, you add the namespace to the query and pass in the manager, like so.
XmlNodeList nodes = xmlDoc.SelectNodes("/r:restaurants/r:restaurant", nsMgr);
and
XmlNode titleNode = itemNode.SelectSingleNode("r:name", nsMgr);
But if you're happy with the other solution and can manipulate it in this way then go for it I guess.
If you remove this xmlns="http://www.algonquincollege.com/onlineservice/reviews"
in your xml it works. I don't know why but the xmlDoc.SelectNodes("/restaurants/restaurant");
do not find any nodes with this xmlns namespace.
This is the code I worked with and it works:
string xml = @"<?xml version=""1.0""?>
<restaurants xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<restaurant>
<name>Laughing Man</name>
<logo>
<name>Visit the Laughing Man</name>
<imagefile>laughing-man.gif</imagefile>
<width unit=""px"">50</width>
<height unit=""px"">200</height>
</logo>
</restaurant>
<restaurant>
<name>Gong’s Asian Cuisine</name>
<logo>
<name/>
<imagefile>gong-asian-cuisine.gif</imagefile>
<width unit=""px"">150</width>
<height unit=""px"">250</height>
</logo>
</restaurant>
</restaurants>";
List<string> names = new List<string>();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
XmlNodeList nodes = xmlDoc.SelectNodes("/restaurants/restaurant");
foreach (XmlNode itemNode in nodes)
{
XmlNode titleNode = itemNode.SelectSingleNode("name");
if (titleNode != null)
{
names.Add(titleNode.InnerText);
}
}
The problem was with namespace. Thanks to @Sean in the comment section I have resolved the issue. Thanks to @Presi also for pointing out the namespace attribute was the problem.
List<string> names = new List<string>();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(HttpContext.Current.Server.MapPath(@"~/App_Data/restaurant_reviews.xml"));
var namespaceName = "ns";
var namespacePrefix = string.Empty;
XmlNamespaceManager nameSpaceManager = null;
if (xmlDoc.LastChild.Attributes != null)
{
var xmlns = xmlDoc.LastChild.Attributes["xmlns"];
if (xmlns != null)
{
nameSpaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
nameSpaceManager.AddNamespace(namespaceName, xmlns.Value);
namespacePrefix = namespaceName + ":";
}
}
XmlNodeList nodes = xmlDoc.SelectNodes(string.Format("/{0}restaurants/{0}restaurant", namespacePrefix), nameSpaceManager);
foreach (XmlNode itemNode in nodes)
{
XmlNode titleNode = itemNode.SelectSingleNode(namespacePrefix + "name", nameSpaceManager);
if (titleNode != null)
{
names.Add(titleNode.InnerText);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.