【问题标题】:Using XmlReader how do I restart at the beginning?使用 XmlReader 如何从头开始重新启动?
【发布时间】:2013-10-10 17:48:18
【问题描述】:

这真的是一个两部分的问题......

  1. 我有一个从内存流创建的 XmlReader 对象。我已经使用了几次 .Read() 方法,现在我想回到开头并从声明节点重新开始。我该怎么做?

  2. 在创建 XmlReader 对象时,我创建了一个 XmlDocument 对象和一个 MemoryStream 对象。在使用内存流创建 XmlReader 之后,是否需要以某种方式销毁这些对象?或者销毁它们也会影响 XmlReader 对象?

这就是我创建 XmlReader 对象的方式

XmlReader xmlReader = null;
XmlDocument doc = new XmlDocument();
doc.Load(m_sXMLPath);

if (doc.FirstChild.NodeType == XmlNodeType.XmlDeclaration)
{
    XmlDeclaration dec = null;
    byte[] bytes = null;
    MemoryStream ms = null;

    dec = (XmlDeclaration)doc.FirstChild;
    switch (dec.Encoding.ToLower())
    {
        case "utf-8":
            bytes = Encoding.UTF8.GetBytes(File.ReadAllText(m_sXMLPath));
            break;
        case "utf-16":
            bytes = Encoding.Unicode.GetBytes(File.ReadAllText(m_sXMLPath));
            break;
        default:
            throw new XmlException("");
    }

    if (bytes != null)
    {
        ms = new MemoryStream(bytes);
        xmlReader = XmlReader.Create(ms);
    }
}

【问题讨论】:

    标签: c# xml


    【解决方案1】:

    您无法重新开始您的 XmlReader 对象。根据微软的文档:

    XmlReader 提供对 XML 数据流的只进、只读访问。 XmlReader 类符合 W3C 可扩展标记语言 (XML) 1.0 和 XML 中的命名空间建议。 http://msdn.microsoft.com/en-us/library/System.Xml.XmlReader.aspx

    如果由于某种原因您确实需要回到开头,则应该使用您的XmlReader 来加载XDocument 对象。然后,您可以使用 XDocument 对象来查询 XML 的任何部分。此外,您应该将基于 Stream 的对象包装在 using 块中,这样您就不必担心破坏。示例如下:

    XDocument myXmlDoc;
    using(MemoryStream ms = new MemoryStream(bytes))
    {
         using(XmlReader xmlReader = XmlReader.Create(ms))
         {
               myXmlDoc = XDocument.Load(xmlReader);
    
               //query your XDocument here to your heart's desire here in any order you want
          }
     }
    

    如果您不熟悉 LINQ to XML,请查看文档here

    如果您不想使用XDocument 并坚持使用XmlDocument,您也可以使用它(无需查询)重新遍历您的XML 文档。无论哪种方式,您都不需要在处理完 XmlDocument(或 XDocument)后丢弃它,因为它不是一次性物品。

    【讨论】:

    • 所以要回答我的第二个问题,我不需要对 XmlDocument 做任何事情,但是否需要对 MemoryStream 做一些事情对吗?如果我将它包装在 using 语句中并在 using 语句中创建 XmlReader 对象,那么在 using 语句之外引用 XmlReader 对象是否仍然可以?
    • @ArvoBowen 正确。但是正如@JohnSaunders 提到的那样,您实际上也不需要使用MemoryStream。只需打开 XML 文件的 TextStream,然后将 TextStream 传递给 XDocument.Load(stream)XmlDocument.Load(stream) 函数。此负载应在 using 块内。与范围一样,您不能引用块之外的流,但是您不需要,因为您的 XmlDocumentXDocument 现在包含整个 XML。
    • 如果您不想创建 XDocument 或 XElement,可以将 MoveToElement() 与 reader.ReadSubtree() 结合使用,以一遍又一遍地读取 xml。如果从顶部元素开始,这可以是整个 xml 字符串。我只是将每个 reader.ReadSubtree() 传递给一个方法,该方法确保在我完成后处理它。
    【解决方案2】:

    您使用 XmlReader 的方式毫无意义。将数据加载到XmlDocumentXDocument 会更好)后,使用XmlReader 没有任何意义。

    在 .NET 中,通常不需要在使用后销毁对象 - 这就是垃圾收集器的用途。

    【讨论】:

    • 尽管您是绝对正确的,因为垃圾回收通常不需要销毁对象,但他确实询问了 MemoryStreamXmlReader 对象。最佳做法是在使用后至少调用 .Close(),或者更好地包裹在 using 中,或者在使用 IDisposable 对象或流时尝试、捕获、最终构造。
    • @JNYRanger: 是的,但是如果他使他的代码合理,它将既不使用 XmlReader 也不使用 MemoryStream,因此 using 将不适用,这就是我没有提及它的原因(相反我通常的做法)。
    • 触摸。在我认为最初读取 XML 数据的某个时候,他需要使用流,所以这就是我提到它的原因。
    猜你喜欢
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 2017-06-12
    • 1970-01-01
    • 2020-12-26
    • 2022-09-23
    相关资源
    最近更新 更多