【问题标题】:Is it possible to save the current XMLReader Position for later use?是否可以保存当前的 XMLReader Position 供以后使用?
【发布时间】:2012-12-22 12:09:33
【问题描述】:

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

我知道XMLReader 对象只是向前的,因此我希望能够保存当前的阅读位置,这样我就可以从我停止阅读的地方继续阅读。

有可能吗?
我知道这可能很棘手,因为XMLreader 读取了大块内存块,所以恢复当前 XML 元素读取点可能会是个问题。

请仅在您确定的情况下提供建议,这将根据您在此问题上的具体经验而起作用。

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

【问题讨论】:

  • 在使用XMLReader 之前,您是否尝试过设置Stream.Position 属性?这应该行得通。
  • 是的,我做到了,Stream 有一种奇怪的位置,显然无法翻译回 Xml 中的特定阅读点元素
  • 对,但是如果你得到Stream.Position,然后在你把它给一个新的XMLReader之前把它设置回原来的位置,它应该从同一个地方拾取。
  • 这可能会有所帮助:stackoverflow.com/questions/2160533/…
  • 是的,看起来你能做的最好的事情就是从XmlTextReader 获取行号,然后,当你下次打开流时,循环遍历流中的每一行直到您到达该行号。它不会很漂亮,但似乎这是最好的选择。

标签: c# .net xml xml-serialization xmlreader


【解决方案1】:

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

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

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

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 的结构(换行符、节点等)始终相同时,它才会起作用。在其他情况下,它将不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 2017-02-23
    相关资源
    最近更新 更多