Читать XElement из XmlReader

Я играю с синтаксическим анализом XML-потока XMPP. Сложность XML-потока заключается в том, что начальный тег не закрывается до конца сеанса, т.е. полная DOM никогда не получается.

<stream:stream>
    <features>
       <starttls />
    </features>
    ....
    network session persists for arbitrary time
    ....
 </stream:stream>

Мне нужно читать элементы XML из потока, не беспокоясь о том, что корневой элемент не был закрыт.

В идеале это сработает, но это не так, и я предполагаю, что это потому, что читатель ожидает закрытия корневого элемента.

XElement someElement = XNode.ReadFrom(xmlReader) as XElement;

Код ниже (который я позаимствовал из Jacob Reimers) действительно работает, но я надеюсь, что есть более эффективный способ, который не требует создания нового XmlReader и выполнения синтаксического анализа строк.

 XmlReader stanzaReader = xmlReader.ReadSubtree();
 stanzaReader.MoveToContent();
 string outerStanza = stanzaReader.ReadOuterXml();
 stanzaReader.Close();
 XElement someElement = XElement.Parse(outerStanza);

person sipsorcery    schedule 15.11.2010    source источник


Ответы (1)


Вам не нужно работать со струнами; вы должны иметь возможность использовать XElement.Load в поддереве:

XElement someElement;
using(XmlReader stanzaReader = xmlReader.ReadSubtree()) {
    someElement = XElement.Load(stanzaReader);
}

И обратите внимание, что это на самом деле не «новый» xml-reader - он сильно привязан к внешнему считывателю (но ограничен набором узлов).

person Marc Gravell    schedule 15.11.2010
comment
Учитывая ваш пример, я не понимаю, почему XmlReader stanzaReader = XElement.Load (xmlReader.ReadSubtree ()) не выполняет эту работу. У меня все еще будет xmlReader в блоке using, и он позаботится о любой очистке. - person sipsorcery; 16.11.2010
comment
@sipwiz - в этом конкретном случае вам, вероятно, это сойдет с рук; Я просто глубоко убежден: избавляйтесь от каждого IDisposable как можно скорее. stanzaReader - это, в конечном счете, другой объект. - person Marc Gravell; 16.11.2010
comment
Ранние версии синтаксического анализатора .net ожидали, пока буферизуется 4 КБ за раз. Вот почему я закончил перенос парсера XP Джеймса Кларка с Java на C # для jabber-net. - person Joe Hildebrand; 06.12.2010