2010-11-07 61 views
3

大家好 我試圖寫一個簡單的xml讀取器,但發現它無意中跳過了xml文件中的其他元素。c#簡單的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> 
+0

你什麼輸出? – jgauffin 2010-11-07 12:51:13

+0

爲什麼不使用linq到xml? – 2010-11-07 12:53:25

+0

您的示例不能編譯。既然你有bug,我們需要看代碼。 – Les 2010-11-07 13:11:42

回答

3

的Read()方法將首先返回列元素,則列「文本」,則結束元素。當您使用ReadElementContentAsFloat時,它讀取當前內容,然後將下一個Read()定位到下一個「文本」部分。由於您的循環跳過文字和結束元素,它錯過2,4,...

試試這個...根據@Shadow嚮導的回答

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

太棒了! 謝謝,它工作正常,我理解它 :) – Iain 2010-11-07 14:25:23

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

編寫自己的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; }