简体   繁体   English

C# - 无法从 xml 文件中获取节点值

[英]C# - Unable to get node value from xml file

I'm trying to get the inner text from a node after loading the XML file.加载 XML 文件后,我试图从节点获取内部文本。 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 文件 - 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&#x2019;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 C# 代码

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.虽然这个问题已经有一个公认的答案,但我还是想添加这个,因为以这种方式删除命名空间和操作 XML 对我来说并不合适,我怀疑它是出于某种原因添加的。

What I believe is the correct approach is too add an XML Namespace Manager to your XPath query.我认为正确的方法是将 XML 命名空间管理器添加到您的 XPath 查询中。

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.然后在 SelectNodes 和 SelectSingleNodes 中,将命名空间添加到查询并传入管理器,就像这样。

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.如果您在您的 xml 中删除此xmlns="http://www.algonquincollege.com/onlineservice/reviews"它将起作用。 I don't know why but the xmlDoc.SelectNodes("/restaurants/restaurant");我不知道为什么,但是xmlDoc.SelectNodes("/restaurants/restaurant"); do not find any nodes with this xmlns namespace.找不到任何具有此 xmlns 命名空间的节点。

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&#x2019;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.感谢评论部分中的@Sean 我已经解决了这个问题。 Thanks to @Presi also for pointing out the namespace attribute was the problem.感谢@Presi 还指出了命名空间属性是问题所在。

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);
                }

            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM