是否可以保存当前XMLReader位置以供以后使用?

本文关键字:位置 XMLReader 保存 是否 | 更新日期: 2023-09-27 17:49:21

我已经从Stream对象中创建了一个XMLReader对象,这个对象是我之前由XMLWriter对象写入的。

我知道XMLReader对象仅向前,因此我希望能够保存当前的读取位置,因此我将能够从我停止读取的地方继续读取。

有可能吗?
我知道这可能是棘手的,因为XMLreader读取内存块,所以也许这将是一个问题,以恢复当前的XML元素读取点。

请仅在您确定的情况下给出建议,它将根据您的经验具体解决此问题。

注意:
1. 我想简单地保存整个XMLReader对象引用的场景。
2. XMLReader Position =当前读取元素的指针,而不是Stream.Position,因为它是其他元素

是否可以保存当前XMLReader位置以供以后使用?

我在一个项目中工作,其中一个外部系统写xml(没有定义的命名空间),我们需要读取它们以查找具有一些特殊值的节点:

  • 当值没有准备好时,我们在几分钟后重新读取。
  • 在其他情况下,我们处理节点(属性,值等)

所以,我认为这段代码可以帮助你:

var input1 = @"<root>
 <ta>
   <XGLi6id90>774825484.1418393</XGLi6id90>
   <VAfrBVB>
     <EG60sk>1030847709.7303829</EG60sk>
     <XR>NOT_READY</XR>
   </VAfrBVB>
 </ta>
 <DxshpR>1123</DxshpR>

var input2 = @"<root>
 <ta>
   <XGLi6id90>774825484.1418393</XGLi6id90>
   <VAfrBVB>
     <EG60sk>1030847709.7303829</EG60sk>
     <XR>99999999</XR>
   </VAfrBVB>
 </ta>
 <DxshpR>1123</DxshpR>

var stream1 = new MemoryStream(Encoding.UTF8.GetBytes(input1));
var stream2 = new MemoryStream(Encoding.UTF8.GetBytes(input2));
stream1.Position = 0;
stream2.Position = 0;
var position1 = DoWork(stream1, new Position());
var position2 = DoWork(stream2, position1);
    public static Position DoWork(Stream stream, Position position)
    {
        using (XmlTextReader xmlTextReader = new XmlTextReader(stream))
        {
            using (XmlReader xmlReader = XmlReader.Create(xmlTextReader, xmlReaderSettings))
            {
                // restores the last position 
                xmlTextReader.SetPosition(position);
                System.Diagnostics.Debug.WriteLine(xmlReader.Value); // Second time prints 99999999
                while (xmlReader.Value != "NOT_READY" && xmlReader.Read())
                {
                    // a custom logic to process nodes....
                }
                // saves the position to process later ...
                position = xmlTextReader.GetPosition();
                System.Diagnostics.Debug.WriteLine(xmlReader.Value); // First time prints NOT_READY
            }
        }
        return position;
    }
}
public class Position
{
    public int LinePosition { get; set; }
    public int LineNumber { get; set; }
}
public static class XmlReaderExtensions
{
    public static void SetPosition(this XmlTextReader xmlTextReader, Position position)
    {
        if (position != null)
        {
            while (xmlTextReader.LineNumber < position.LineNumber && xmlTextReader.Read())
            {
            }
            while (xmlTextReader.LinePosition < position.LinePosition && xmlTextReader.Read())
            {
            }
        }
    }
    public static Position GetPosition(this XmlTextReader xmlTextReader)
    {
        Position output;
        if (xmlTextReader.EOF)
        {
            output = new Position();
        }
        else
        {
            output = new Position { LineNumber = xmlTextReader.LineNumber, LinePosition = xmlTextReader.LinePosition };
        }
        return output;
    }
}

很重要,而且很明显,只有当xml的结构(换行符、节点等)总是相同时,它才会起作用。在其他情况下,它将不起作用。