Кажется, что каждый раз, когда я использую XMLReader, я сталкиваюсь с кучей проб и ошибок, пытаясь понять, что я собираюсь прочитать, что я читаю, что я только что прочитал. В конце концов, я всегда в этом разбираюсь, но, тем не менее, после многократного использования я, похоже, не совсем понимаю, что на самом деле делает XMLReader, когда я вызываю различные функции. Например, когда я вызываю Read в первый раз, если он читает начальный тег элемента, он сейчас находится в конце тега элемента или готов начать чтение атрибутов элемента? Знает ли он значения атрибутов, если я вызываю GetAttribute? Что произойдет, если я вызову ReadStartElement на этом этапе? Закончит ли он чтение начального элемента или ищет следующий, пропуская все атрибуты? Что делать, если я хочу прочитать несколько элементов - как лучше всего попытаться прочитать следующий элемент и определить его имя. Будет ли работать Read с последующим IsStartElement или IsStartElement будет возвращать информацию об узле после элемента, который я только что прочитал?
Как вы можете видеть, мне действительно не хватает понимания того, где находится XMLReader на разных этапах его чтения и как на его состояние влияют различные функции чтения. Есть ли какая-то простая модель, которую я просто не заметил?
Вот еще один пример проблемы (взят из ответов):
string input = "<machine code=\"01\">The Terminator" +
"<part code=\"01a\">Right Arm</part>" +
"<part code=\"02\">Left Arm</part>" +
"<part code=\"03\">Big Toe</part>" +
"</machine>";
using (System.IO.StringReader sr = new System.IO.StringReader(input))
{
using (XmlTextReader reader = new XmlTextReader(sr))
{
reader.WhitespaceHandling = WhitespaceHandling.None;
reader.MoveToContent();
while(reader.Read())
{
if (reader.Name.Equals("machine") && (reader.NodeType == XmlNodeType.Element))
{
Console.Write("Machine code {0}: ", reader.GetAttribute("code"));
Console.WriteLine(reader.ReadElementString("machine"));
}
if(reader.Name.Equals("part") && (reader.NodeType == XmlNodeType.Element))
{
Console.Write("Part code {0}: ", reader.GetAttribute("code"));
Console.WriteLine(reader.ReadElementString("part"));
}
}
}
}
Первая проблема, узел машины полностью пропущен. MoveToContent, кажется, перемещается к содержимому машинного элемента, в результате чего он никогда не анализируется. Кроме того, если вы пропустите MoveToContent, вы получите ошибку: «Элемент» является недопустимым XmlNodeType. » пытаюсь прочитать строку, которую я не могу объяснить.
Следующая проблема заключается в том, что при чтении первого элемента части ReadElementString, кажется, позиционирует читателя в начале следующего элемента части после чтения. Это приводит к тому, что reader.Read в начале следующего цикла пропускает следующий элемент детали, переходя вправо к последнему элементу детали. Итак, окончательный вывод этого кода:
Код детали 01a: Правая рука
Код детали 03: Большой палец
Это яркий пример непонятного поведения XMLReader, которое я пытаюсь понять.