2010-11-15 9 views
8

Używam parsowania strumienia XML XMPP. Podatnością w strumieniu XML jest to, że znacznik początkowy nie zostaje zamknięty do końca sesji, tzn. Kompletny DOM nigdy nie jest odbierany.Przeczytaj XElement z XmlReadera

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

Muszę odczytywać elementy XML ze strumienia, nie przejmując się tym, że element główny nie został zamknięty.

Idealnie by było, ale nie działa i zakładam, że to dlatego, że czytnik czeka na zamknięcie elementu głównego.

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

Poniższy kod (który pożyczyłem od Jacob Reimers) działa, ale mam nadzieję, że jest bardziej efektywny sposób, który nie wymaga tworzenia nowego XmlReader i robi parsowania ciąg.

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

Odpowiedz

10

Nie powinieneś pracować ze strunami; należy móc korzystać XElement.Load na poddrzewa:

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

i zauważ, że to naprawdę nie jest „nowy” xml-czytnik - jest mocno przywiązany do zewnętrznego czytnika (ale ograniczone do zestawu węzłów).

+0

Podany przykład nie można zrozumieć, dlaczego XmlReader stanzaReader = XElement.Load (xmlReader.ReadSubtree()) nie wykonałby zadania. Nadal będę mieć xmlReader w bloku używając, który zajmie się czyszczeniem. – sipwiz

+0

@sipwiz - w tym konkretnym przypadku prawdopodobnie unikniesz tego; Jestem po prostu głęboko zakorzeniony: natychmiast wyrzuć * każde * 'IDisposable'. 'stanzaReader' to ostatecznie inny obiekt. –

+0

Wcześniejsze wersje analizatora ściągnięć .net czekały na buforowanie po 4kB jednocześnie. Właśnie dlatego dołączyłem parser XP Jamesa Clarka z Java do C# dla jabber-net. –