Кажется, каждый раз, когда я использую XMLReader, я получаю кучу проб и ошибок, пытаясь понять, что я собираюсь читать, и то, что я читаю, и то, что я только что прочитал. Я всегда понимаю это в конце, но я все же, после использования его несколько раз, похоже, не имеет четкого понимания того, что делает XMLReader, когда я называю различные функции. Например, когда я вызываю Read в первый раз, если он читает начальный тег элемента, находится ли он в конце тега элемента или готов начать чтение атрибутов элемента? Знает ли он значения атрибутов, если я вызываю GetAttribute? Что произойдет, если я назову ReadStartElement? По завершении чтения элемента запуска или поиска следующего, пропустив все атрибуты? Что делать, если я хочу прочитать несколько элементов - лучший способ попробовать прочитать следующий элемент и определить его имя. Будет ли Read, за которым следует IsStartElement, или IsStartElement будет возвращать информацию о node после элемента, который я только что прочитал?
Как вы видите, мне действительно не хватает понимания того, где находится 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"));
}
}
}
}
Первая проблема, машина node полностью пропущена. Кажется, MoveToContent перемещается к содержимому элемента машины, заставляя его никогда не разбираться. Кроме того, если вы пропустите MoveToContent, вы получите сообщение об ошибке: "Элемент" является недопустимым XmlNodeType ". пытаясь прочитать элемент ReadElementString, который я не могу объяснить.
Следующая проблема заключается в том, что, читая элемент первой части, ReadElementString, кажется, позиционирует читателя в начале следующего элемента элемента после прочтения. Это заставляет читателя. Прочитайте в начале следующего цикла, чтобы пропустить следующий элемент детали, прыгающий прямо к последнему элементу детали. Таким образом, окончательный вывод этого кода:
Код детали 01a: Правая рука
Код детали 03: Big Toe
Это яркий пример противоречивого поведения XMLReader, который я пытаюсь понять.