【问题标题】:c# simple xml reader skips every other elementc#简单的xml阅读器跳过所有其他元素
【发布时间】:2010-11-07 12:45:39
【问题描述】:

大家好 我曾尝试编写一个简单的 xml 阅读器,但发现它无意中跳过了 xml 文件中的所有其他元素。

我猜我告诉它两次移动到下一个元素,但我不确定发生了什么或解决方案是什么。

任何帮助将不胜感激:)

这里是代码示例和xml文件示例

public LevelLoader(string theLevelFile ,ContentManager theContent)
    {
        XmlTextReader reader = new XmlTextReader(theLevelFile);
        while (reader.Read())
        {               
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.Name)
                {
                    case "tilerow":
                    {                            
                        currentRow = currentRow + 1;
                        Console.WriteLine("row found");
                        currentCol = 0;
                        break;
                    }

                    case "tilecol":
                    {
                        Console.WriteLine("col found");                                                                                                                         
                        currentTexture = reader.ReadElementContentAsFloat();                          
                        currentCol = currentCol + 1;
                        break;
                    }
                }
            }
        }
    }

示例 xml

<tilerow>
<tilecol>1</tilecol><tilecol>2</tilecol><tilecol>3</tilecol><tilecol>4</tilecol><tilecol>5</tilecol><tilecol>6</tilecol><tilecol>7</tilecol><tilecol>8</tilecol><tilecol>9</tilecol><tilecol>10</tilecol>
</tilerow>

【问题讨论】:

  • 为什么不用linq to xml?
  • 您的示例无法编译。既然你有bug,我们需要看代码。
  • 对我来说编译得很好,他正在使用我删除的一些全局成员
  • 它缺少虚空,但这已经够小了,晨雾还没有完全消散。

标签: c# xml xmlreader


【解决方案1】:

Read() 方法将首先返回 Column 元素,然后是 Column “Text”,然后是 EndElement。当您使用 ReadElementContentAsFloat 时,它会读取当前内容,然后将下一个 Read() 定位到下一个“文本”部分。由于您的循环跳过了 Text 和 EndElement,因此它错过了 2、4、...

试试这个吧……

case "tilecol": 
{ 
Console.WriteLine("col found");
reader.Read();
float.TryParse(reader.Value, out currentTexture);
currentCol = currentCol + 1;
break;
} 

【讨论】:

    【解决方案2】:

    查看此页面:http://msdn.microsoft.com/en-us/library/ms223980.aspx

    简而言之,ReadElementContentAsFloat 将阅读器移动到下一个元素,循环的“主要” reader.Read() 也是如此。

    这是考虑到这种新行为的新循环:

    while (!reader.EOF)
    {
        bool needToRead = true;
        if (reader.NodeType == XmlNodeType.Element)
        {
            switch (reader.Name)
            {
                case "tilerow":
                    currentRow = currentRow + 1;
                    Console.WriteLine("row found");
                    currentCol = 0;
                    break;
    
                case "tilecol":
                    Console.WriteLine("col found");                                                                                                                         
                    currentTexture = reader.ReadElementContentAsFloat();                          
                    currentCol = currentCol + 1;
                    needToRead = false;
                    break;
            }
        }
        if (needToRead)
            reader.Read();
    }
    

    【讨论】:

      【解决方案3】:

      根据@Shadow Wizard 在可序列化类中编写自己的ReadXml 方法时的回答TileRow

      public void ReadXml(XmlReader reader)
      {
          reader.Read();
          do
          {
              if (!XmlNodeType.Element.Equals(reader.NodeType))
              {
                  if (!XmlNodeType.EndElement.Equals(reader.NodeType))
                  {
                      log.error(reader.NodeType + " is an unknown NodeType for " + this.GetType());
                  }
                  // return while further reading would move the reader position to another / outer element and will lead to skipped elements in parser
                  return;
              }
              switch (reader.Name)
              {
                  case "tilecol":
                      col = reader.ReadElementContentAsFloat();
                      break;
      
                   default:
                      log.error(reader.Name + " is not a valid XMLElement for " + this.GetType());
                      reader.Read();
                      break;
              }
          }
          while (!reader.EOF);
       }
      

      对于手动编写器:

      public void WriteXml(XmlWriter writer)
      {
          writer.WriteElementString("tilecol", col.ToString());
      }
      

      这样您就可以将TileRow 用作 XMLElement

      [XmlElement]
      public TileRow tileRow { get; set; }
      

      【讨论】:

        猜你喜欢
        • 2012-04-19
        • 2013-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多