【问题标题】:C# - Unable to get node value from xml fileC# - 无法从 xml 文件中获取节点值
【发布时间】:2020-04-01 09:22:53
【问题描述】:

我试图在加载 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# 代码

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

}

【问题讨论】:

标签: c# xml


【解决方案1】:

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

我认为正确的方法是将 XML 命名空间管理器添加到您的 XPath 查询中。

var nsMgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsMgr.AddNamespace("r", "http://www.algonquincollege.com/onlineservice/reviews");

然后在您的 SelectNodes 和 SelectSingleNodes 中,将命名空间添加到查询并传入管理器,就像这样。

XmlNodeList nodes = xmlDoc.SelectNodes("/r:restaurants/r:restaurant", nsMgr);

XmlNode titleNode = itemNode.SelectSingleNode("r:name", nsMgr);

但是,如果您对其他解决方案感到满意并且可以以这种方式对其进行操作,那么我想就去做吧。

【讨论】:

  • 谢谢@Ryan Thomas,我将 Presi 的回答视为已接受,因为它正在解决问题。然而,你和肖恩的答案是我正在寻找的实际答案。
  • 我认为这是一个很好的解决方案。不知道 XmlNamespaceManager。因此我删除了它。但你的答案是更好的解决方案!
【解决方案2】:

如果你在你的 xml 中删除这个 xmlns="http://www.algonquincollege.com/onlineservice/reviews" ,它就可以工作。我不知道为什么,但是 xmlDoc.SelectNodes("/restaurants/restaurant"); 找不到任何具有此 xmlns 命名空间的节点。

这是我使用的代码,它可以工作:

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

【讨论】:

  • 非常感谢。这两天我一直在敲头。那个链接是问题所在。
  • @Abdullah-Al-Nahian 很高兴我能帮你!
  • 就个人而言,我不认为以这种方式删除 XML 命名空间是一个好主意,所以我添加了一个替代答案。
  • @Presi 很抱歉将您的答案删除为已接受的答案。因为我想让每个人都知道最准确的一个。由 Sean 和 Ryan 提供。还是你的帮了我很大的忙。谢谢你的朋友。
【解决方案3】:

问题出在命名空间上。感谢评论部分的@Sean,我已经解决了这个问题。感谢@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);
                }

            }

【讨论】:

  • 很好的答案!我知道这不是删除命名空间的最佳解决方案。因此,您的代码要好得多,并且是正确的解决方案。
猜你喜欢
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 2020-09-03
  • 2018-02-22
  • 1970-01-01
  • 2013-08-12
相关资源
最近更新 更多