从 XmlReader 中读取 XElement

8
我正在尝试解析XMPP XML流。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);
1个回答

13

你不需要直接操作字符串;可以使用XElement.Load来处理子树:

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

请注意,这并不是一个真正的“新”的XML阅读器 - 它与外部阅读器紧密联系(但受限于一组节点)。


根据你的示例,我看不出为什么XmlReader stanzaReader = XElement.Load(xmlReader.ReadSubtree())不能胜任。我仍然会将xmlReader放在using块中,这将处理任何清理工作。 - sipsorcery
@sipwiz - 在那种特殊情况下,你可能可以逃脱; 我只是根深蒂固:立即处理每个 IDisposablestanzaReader 是另一个不同的对象。 - Marc Gravell
早期版本的.NET拉解析器会等待4KB的缓冲区。这就是为什么我最终将James Clark的XP解析器从Java移植到C#用于jabber-net的原因。 - Joe Hildebrand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接