是否有办法通过XmlReader获取正在检查的节点流中的当前位置?
我想使用XmlReader解析文档并保存某些元素的位置,以便以后可以查找。
附录:
我正在通过WPF控件生成Xaml。 Xaml不应经常更改。 Xaml中有一些占位符,我需要替换项目,有时需要循环。我认为用代码而不是进行转换可能会更容易(我对此可能是错的)。我的想法是将其解析为一个简单的数据结构,该数据结构需要替换什么以及在哪里,然后使用StringBuilder通过从xaml字符串复制块来产生最终输出。
[正如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进行测试,但也应适用于其他工具。
只需提出一个建议就可以了:您可以保留对传入XmlReader
的基础流的引用,并记下其位置-但这会给您错误的结果,例如读者几乎肯定会缓冲其输入(即,它将读取前1024个字符或其他内容-因此,您的第一个节点可能“显示”为1024个字符)。
[如果您使用XmlTextReader
而不只是XmlTextReader
,那么它将实现XmlReader
,这意味着您可以随时要求XmlReader
和IXmlLineInfo
-这样对您够好吗? (坦率地说,您可能应该先检查IXmlLineInfo
。)
编辑:我刚刚注意到您希望以后能够搜索到该位置...在这种情况下,行信息可能不会有很大帮助。在文本编辑器中查找内容非常有用,但对于移动文件指针却不是那么重要。您能否提供有关您要做什么的更多信息?解决这个问题可能有更好的方法。
我已经为此解决了一个问题,尽管它可能无法在每种情况下都起作用,并且对.NET Framework类的私有成员使用了反射,但是我能够使用所示的扩展方法来计算LineNumber
的正确位置下面。
您的LineNumber
必须使用基础LinePosition
从LinePosition
创建(我没有尝试过其他HasLineInfo()
,只要它们报告其位置,它们就可以正常工作)。
我已经在此处发布了详细信息:HasLineInfo()
XmlReader
我有相同的问题,显然没有简单的解决方案。
所以我决定操纵两个只读FileStream:一个用于XmlReader,另一个用于获取每一行的位置:
XmlReader
这不是最佳方法,因为它使用两个读取器。为避免这种情况,我们可以重写XmlReader和行计数器之间共享的新FileReader。但这只是为您提供您感兴趣的线的偏移量。要获得标签的确切偏移量,我们应该使用LinePosition,但是由于Encoding的原因,这可能会很棘手。
感谢Geoff的回答。它在Windows 7上可以正常工作。但是,以某种方式在mscorlib.dll的Windows Server 2003上使用.net 4版本时,我必须更改以下2个功能才能正常工作。
StreamReader
此外,应该偷看GetPosition方法中的底层StreamReader,以前进指针。
FileStream
Streams