2010-11-15 58 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