2010-11-15 59 views
8

我在解析一個XMPP XML流。關於XML流的棘手問題是,直到會話結束時,start標記纔會被關閉,即從未接收到完整的DOM。從XmlReader讀取XElement

<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); 

回答

10

你不應該需要使用字符串;你應該能夠在子樹使用XElement.Load

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

而且注意,這是不是一個真正的「新」的XML閱讀器 - 它嚴重依賴於外讀卡器(但受限於一組的節點)。

+0

鑑於你的例子,我不明白爲什麼XmlReader stanzaReader = XElement.Load(xmlReader.ReadSubtree())不會做這項工作。我仍然將xmlReader放在一個使用塊中,並且會處理任何清理。 – sipwiz 2010-11-16 09:35:04

+0

@sipwiz - 在這種特殊情況下,你可能會逃避它;我只是根深蒂固:立即處置*每個*'IDisposable'。最終,「stanzaReader」是一個不同的對象。 – 2010-11-16 14:20:28

+0

早期版本的.net的pull解析器將一次等待4kB緩衝。這就是爲什麼我最終將James Clark的XP解析器從Java移植到了C#的jabber-net。 – 2010-12-06 09:29:06