从XmlReader获取当前位置

问题描述 投票:21回答:6

是否有办法通过XmlReader获取正在检查的节点流中的当前位置?

我想使用XmlReader解析文档并保存某些元素的位置,以便以后可以查找。

附录:

我正在通过WPF控件生成Xaml。 Xaml不应经常更改。 Xaml中有一些占位符,我需要替换项​​目,有时需要循环。我认为用代码而不是进行转换可能会更容易(我对此可能是错的)。我的想法是将其解析为一个简单的数据结构,该数据结构需要替换什么以及在哪里,然后使用StringBuilder通过从xaml字符串复制块来产生最终输出。

.net xmlreader
6个回答
9
投票

[正如Jon Skeet所说,XmlTextReader实现了IXmlLineInfo,但由于XmlTextReader而弃用了.NET 2.0,问题仅是关于XmlReader。我找到了这个解决方案:

XmlReader xr = XmlReader.Create( // MSDN recommends to use Create() instead of ctor()
    new StringReader("<some><xml><string><data>"),
    someSettings // furthermore, can't set XmlSettings on XmlTextReader
);
IXmlLineInfo xli = (IXmlLineInfo)xr;

while (xr.Read())
{
    // ... some read actions ...

    // current position in StringReader can be accessed through
    int line = xli.LineNumber;
    int pos  = xli.LinePosition;
}

P.S。已针对.NET Compact Framework 3.5进行测试,但也应适用于其他工具。


8
投票

只需提出一个建议就可以了:您可以保留对传入XmlReader的基础流的引用,并记下其位置-但这会给您错误的结果,例如读者几乎肯定会缓冲其输入(即,它将读取前1024个字符或其他内容-因此,您的第一个节点可能“显示”为1024个字符)。

[如果您使用XmlTextReader而不只是XmlTextReader,那么它将实现XmlReader,这意味着您可以随时要求XmlReaderIXmlLineInfo-这样对您够好吗? (坦率地说,您可能应该先检查IXmlLineInfo。)

编辑:我刚刚注意到您希望以后能够搜索到该位置...在这种情况下,行信息可能不会有很大帮助。在文本编辑器中查找内容非常有用,但对于移动文件指针却不是那么重要。您能否提供有关您要做什么的更多信息?解决这个问题可能有更好的方法。


8
投票

我已经为此解决了一个问题,尽管它可能无法在每种情况下都起作用,并且对.NET Framework类的私有成员使用了反射,但是我能够使用所示的扩展方法来计算LineNumber的正确位置下面。

您的LineNumber必须使用基础LinePositionLinePosition创建(我没有尝试过其他HasLineInfo(),只要它们报告其位置,它们就可以正常工作)。

我已经在此处发布了详细信息:HasLineInfo()

XmlReader

3
投票

我有相同的问题,显然没有简单的解决方案。

所以我决定操纵两个只读FileStream:一个用于XmlReader,另一个用于获取每一行的位置:

XmlReader

这不是最佳方法,因为它使用两个读取器。为避免这种情况,我们可以重写XmlReader和行计数器之间共享的新FileReader。但这只是为您提供您感兴趣的线的偏移量。要获得标签的确切偏移量,我们应该使用LinePosition,但是由于Encoding的原因,这可能会很棘手。


2
投票

感谢Geoff的回答。它在Windows 7上可以正常工作。但是,以某种方式在mscorlib.dll的Windows Server 2003上使用.net 4版本时,我必须更改以下2个功能才能正常工作。

StreamReader

此外,应该偷看GetPosition方法中的底层StreamReader,以前进指针。

FileStream

0
投票
Streams
© www.soinside.com 2019 - 2024. All rights reserved.