c#simple xml reader跳过其他所有元素

时间:2010-11-07 12:45:39

标签: c# xml xmlreader

大家好 我试图编写一个简单的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>

3 个答案:

答案 0 :(得分:3)

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

试试这个......

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

答案 1 :(得分: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();
}

答案 2 :(得分:0)

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

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