С# простой читатель xml пропускает все остальные элементы

Привет всем, я попытался написать простую программу чтения 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>

person Iain    schedule 07.11.2010    source источник
comment
Почему бы вам не использовать linq to xml?   -  person Oskar Kjellin    schedule 07.11.2010
comment
Ваш образец не компилируется. Поскольку у вас есть ошибка, нам нужно увидеть код.   -  person Les    schedule 07.11.2010
comment
Скомпилировано нормально для меня, он использует некоторые глобальные члены, которые я удалил   -  person Shadow Wizard Wearing Mask V2    schedule 07.11.2010
comment
Не хватает пустоты, но это достаточно незначительно, а утренний туман еще не полностью рассеялся.   -  person Les    schedule 07.11.2010


Ответы (3)


Метод Read() сначала вернет элемент Column, затем столбец «Текст», а затем 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;
} 
person Les    schedule 07.11.2010

См. эту страницу: http://msdn.microsoft.com/en-us/library/ms223980.aspx

Короче говоря, ReadElementContentAsFloat перемещает считыватель к следующему элементу, а также «основной» считыватель.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();
}
person Shadow Wizard Wearing Mask V2    schedule 07.11.2010

согласно ответу @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; }
person childno͡.de    schedule 19.12.2014