【问题标题】:Foreach loop XmlNodeListForeach 循环 XmlNodeList
【发布时间】:2012-08-07 14:15:38
【问题描述】:

目前我有以下代码:

XmlDocument xDoc = new XmlDocument();
xDoc.Load("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter");

XmlNodeList tweets = xDoc.GetElementsByTagName("text");
foreach (int i in tweets)
{
    if (tweets[i].InnerText.Length > 0)
    {
         MessageBox.Show(tweets[i].InnerText);
    }
}

这不起作用,它在 foreach 行上给了我System.InvalidCastException

以下代码完美运行(没有 foreach,i 被零替换):

XmlDocument xDoc = new XmlDocument();
xDoc.Load("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter");

XmlNodeList tweets = xDoc.GetElementsByTagName("text");

if (tweets[0].InnerText.Length > 0)
{
     MessageBox.Show(tweets[0].InnerText);
}

【问题讨论】:

  • tweets 不是一个整数序列——它是一个节点序列......那么你为什么期望能够用foreach (int i in ... 迭代它?

标签: c# foreach xmldocument


【解决方案1】:

我知道已经有一个标记的答案,但你可以像你第一次尝试那样做,你只需要将 int 替换为XmlNode

XmlDocument xDoc = new XmlDocument();
xDoc.Load("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter");

XmlNodeList tweets = xDoc.GetElementsByTagName("text");
foreach (XmlNode i in tweets)
{
    if (i.InnerText.Length > 0)
    {
         MessageBox.Show(i.InnerText);
    }
}

【讨论】:

    【解决方案2】:

    tweets 是一个节点列表。我认为你想要做的是:

    XmlDocument xDoc = new XmlDocument();
    xDoc.Load("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter");
    
    XmlNodeList tweets = xDoc.GetElementsByTagName("text");
    for (int i = 0; i < tweets.Count; i++)
    {
        if (tweets[i].InnerText.Length > 0)
        {
            MessageBox.Show(tweets[i].InnerText);
        }
    }
    

    【讨论】:

    • 只是想发布这是解决方案。谢谢!
    【解决方案3】:

    它不是Int 类型,这就是您遇到强制转换异常的原因。您可以将 int 替换为适当的类型,也可以简单地使用 type inference (implicitly typed variables) 来处理此问题。这里我使用typeinference。通过说类型为var,编译器将理解它是tweets集合中的迭代器变量的类型

    foreach (var i in tweets)
    {
        if (i!=null)
        {
          string tweet= (((System.Xml.XmlElement)(i))).InnerText;
          MessageBox.Show(tweet);
         }
    }
    

    编辑: 使用 Wonderful LINQtoXML,您的代码可以像这样重写。

    string url = "http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=twitter";
    XElement elm = XElement.Load(url);
    if (elm != null)
    {              
        foreach (var status in elm.Elements("status"))
        {
            string tweet = status.Element("text").Value;
            MessageBox.Show(ss);
        }
    }
    

    【讨论】:

    • 我正在使用for 循环,所以我可以遍历它们。感谢您的回答!
    【解决方案4】:

    所有答案似乎都有些过时Imperative 示例,所以我将添加一个声明性的。这不是 OP 想要的,但我相信你会明白的。

        public static List<System.Xml.XmlNode> toList(System.Xml.XmlNodeList nodelist){
            List<System.Xml.XmlNode> nodes =  new List<System.Xml.XmlNode>();
            foreach (System.Xml.XmlNode node in nodelist)
            {
                nodes.Add(node);
            }
            return nodes;
        }
        public static ReadMeObject setXml(ReadMeObject readmeObject){
            readmeObject.xmlDocument = new System.Xml.XmlDocument();
            readmeObject.xmlDocument.LoadXml("<body>"+readmeObject.htmlStringContent+"</body>");
            System.Xml.XmlNodeList images =  readmeObject.xmlDocument.SelectNodes("//img");
            Array.ForEach(
                Functions.toList( images )
                    .Where((image) => image.Attributes != null)
                    .Where((image) => image.Attributes["src"] != null)
                    .Where((image) => image.Attributes["src"].Value != "")
                    .ToArray()                
                , (image) => {
                    Console.WriteLine(image.Attributes["src"].Value);
                }
            );
            return readmeObject;
        }
    

    【讨论】:

      【解决方案5】:
      foreach (XmlNode node in tweets)
      {
          if (tweets[i].InnerText.Length > 0)
          {
               MessageBox.Show(tweets[node].InnerText);
          }
      }
      

      我已将您不能使用的“I”更改为 XmlNode,它会选择列表中的一行。

      【讨论】:

        【解决方案6】:

        您可以使用.GetEnumerator() 循环浏览集合

        此代码取自 Microsoft 文档:

         XmlNodeList elemList = root.GetElementsByTagName("title");
         IEnumerator ienum = elemList.GetEnumerator();          
         while (ienum.MoveNext()) {   
           XmlNode title = (XmlNode) ienum.Current;
           Console.WriteLine(title.InnerText);
         }
        

        【讨论】:

          【解决方案7】:

          使用这个简单的扩展方法来遍历 XmlNodeList:

          public static void ForEachXml<TXmlNode>(this XmlNodeList nodeList, Action<TXmlNode> action)
          {
              foreach (TXmlNode node in nodeList) action(node);
          }
          

          方法调用:

          xDoc.GetElementsByTagName("text").ForEachXML<XmlNode>(tweet => 
              {
                  if (tweet.InnerText.Length > 0)
                      MessageBox.Show(tweet.InnerText);
              });
          
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-05-28
            • 1970-01-01
            • 1970-01-01
            • 2016-09-26
            • 2012-07-19
            • 2020-02-19
            • 2010-09-05
            相关资源
            最近更新 更多