Я пытаюсь как можно быстрее прочитать следующий документ Xml и позволить дополнительным классам управлять чтением каждого подблока.
<ApplicationPool>
<Accounts>
<Account>
<NameOfKin></NameOfKin>
<StatementsAvailable>
<Statement></Statement>
</StatementsAvailable>
</Account>
</Accounts>
</ApplicationPool>
Однако я пытаюсь использовать объект XmlReader для чтения каждой учетной записи, а затем «StatementsAvailable». Вы предлагаете использовать XmlReader.Read, проверять каждый элемент и обрабатывать его?
Я подумал о разделении моих классов, чтобы правильно обрабатывать каждый узел. Итак, есть класс AccountBase, который принимает экземпляр XmlReader, который считывает NameOfKin и несколько других свойств учетной записи. Затем я хотел взаимодействовать через утверждения и позволить другому классу заполнить заявление об утверждении (и впоследствии добавить его в список IList).
До сих пор у меня есть часть «для каждого класса», выполняемая с помощью XmlReader.ReadElementString (), но я не могу понять, как указать указателю перейти к элементу StatementsAvailable и позволить мне перебирать их и позволить другому классу прочитать каждое из этих свойств .
Звучит просто!
Ответы:
По моему опыту
XmlReader
, очень легко случайно прочитать слишком много. Я знаю, вы сказали, что хотите прочитать его как можно быстрее, но пробовали ли вы вместо этого использовать модель DOM? Я обнаружил, что LINQ to XML значительно упрощает работу с XML .Если ваш документ особенно велик, вы можете комбинировать
XmlReader
LINQ to XML, создаваяXElement
из anXmlReader
для каждого из ваших «внешних» элементов в потоковом режиме: это позволяет вам выполнять большую часть работы по преобразованию в LINQ to XML, но при этом требуется только небольшая часть документа в памяти одновременно. Вот пример кода (немного адаптированный из этого сообщения в блоге ):Я использовал это для преобразования пользовательских данных StackOverflow (которые огромны) в другой формат раньше - он работает очень хорошо.
РЕДАКТИРОВАТЬ из radarbob, переформатированный Джоном - хотя не совсем ясно, о какой проблеме "слишком далеко" идет речь ...
Это должно упростить вложение и решить проблему «слишком далеко читать».
Это решает проблему "слишком далекого чтения", поскольку реализует классический шаблон цикла while:
источник
if(reader.Name == elementName)
чтобыwhile(reader.Name == elementName)
исправить проблему, указанную pbz?SimpleStreamAxis()
будет пропускать элементы, если XML не имеет отступа, потому чтоNode.ReadFrom()
позиционирует средство чтения на следующем узле после загруженного элемента - который будет пропущен следующим безусловнымRead()
. Если следующий узел - пробел, значит, все в порядке. В противном случае нет. Версии без этой проблемы можно найти здесь , здесь или здесь .Три года спустя, возможно, с новым акцентом на данные WebApi и xml, я столкнулся с этим вопросом. Поскольку в коде я склонен следовать за Скитом из самолета без парашюта и видеть его исходный код, дважды подтверждаемый статьей команды MS Xml, а также примером в BOL Streaming Transform of Large Xml Docs , я очень быстро пропустил другие комментарии , в частности от 'pbz', который указал, что если у вас есть одинаковые элементы по имени подряд, все остальные пропускаются из-за двойного чтения. Фактически, статьи блога BOL и MS анализировали исходные документы с целевыми элементами, вложенными глубже второго уровня, маскируя этот побочный эффект.
Другие ответы касаются этой проблемы. Я просто хотел предложить немного более простую версию, которая, похоже, пока работает хорошо, и учитывает, что xml может поступать из разных источников, а не только из uri, и поэтому расширение работает с управляемым пользователем XmlReader. Одно предположение состоит в том, что считыватель находится в исходном состоянии, поскольку в противном случае первый Read () может пройти мимо желаемого узла:
источник
else Read()
к обоим. Спасибо, что уловили это.Мы постоянно проводим такой анализ XML. Ключ определяет, где метод синтаксического анализа оставит читателя при выходе. Если вы всегда оставляете читателя на следующем элементе после элемента, который был прочитан первым, вы можете безопасно и предсказуемо читать в потоке XML. Итак, если читатель в настоящее время индексирует
<Account>
элемент, после синтаксического анализа он проиндексирует</Accounts>
закрывающий тег.Код парсинга выглядит примерно так:
Statements
Класс просто читает в<StatementsAvailable>
узлеStatement
Класс будет выглядеть очень то же самоеисточник
Для подобъектов
ReadSubtree()
дает вам xml-reader, ограниченный подобъектами, но я действительно думаю, что вы делаете это трудным путем. Если у вас нет особых требований к обработке необычного / непредсказуемого xml, используйтеXmlSerializer
(возможно, в сочетании с,sgen.exe
если вы действительно хотите).XmlReader
это ... сложно. В отличие от:источник
В следующем примере выполняется навигация по потоку для определения текущего типа узла, а затем использование XmlWriter для вывода содержимого XmlReader.
В следующем примере методы XmlReader используются для чтения содержимого элементов и атрибутов.
источник
Вы можете пройти через xmlnode и получить данные ...... C # XML Reader
источник
У меня нет опыта. Но я думаю, что XmlReader не нужен. Очень сложно использовать.
XElement очень прост в использовании.
Если вам нужна производительность (быстрее), вы должны изменить формат файла и использовать классы StreamReader и StreamWriter.
источник