C# 使用XmlReader如何在开始时重新启动?
这真的是一个由两部分组成的问题C# 使用XmlReader如何在开始时重新启动?,c#,xml,C#,Xml,这真的是一个由两部分组成的问题 我有一个从内存流创建的XmlReader对象。我已经多次使用了.Read()方法,现在我想回到开头,在声明节点重新开始。我该怎么做 在创建XmlReader对象时,我创建了一个XmlDocument对象和一个MemoryStream对象。在使用内存流创建XmlReader之后,是否需要以某种方式销毁这些对象?或者销毁它们也会影响XmlReader对象吗 我就是这样创建XmlReader对象的 XmlReader xmlReader = null; XmlDocum
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);
}
}
无法从头重新启动
XmlReader
对象。根据Microsoft的文档:
XmlReader提供对XML数据流的前向只读访问。XmlReader类符合W3C可扩展标记语言(XML)1.0和XML建议中的名称空间。
如果出于某种原因确实需要回到开头,那么应该使用XmlReader
加载XDocument
对象。然后可以使用XDocument
对象查询XML的任何部分。此外,您应该使用块将基于流的对象包装在中,这样您就不必担心破坏。示例如下:
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
}
}
如果您不熟悉LINQtoXML,请查看文档
如果您不想使用XDocument
并坚持使用XmlDocument
,也可以使用它(无需查询)重新遍历XML文档。不管是哪种方式,尽管您在处理完XmlDocument
(或XDocument
)后不需要处理它,因为它不是一次性对象。您使用XmlReader的方式毫无意义。一旦将数据加载到XmlDocument
(XDocument
会更好),使用XmlReader
就没有意义了
在.NET中,通常不需要在使用后销毁对象—这就是垃圾收集器的作用。所以要回答我的第二个问题,我不需要对XmlDocument做任何事情,但需要对MemoryStream做一些事情,对吗?如果我将其包装在using语句中,并在using语句中创建一个XmlReader对象,那么当在using语句外部引用时,XmlReader对象是否仍然正常?@ArvoBowen Correct。但是正如@JohnSaunders所提到的,您实际上也不需要使用MemoryStream
。只需打开XML文件的文本流,并将文本流传递给XDocument.Load(stream)
或XmlDocument.Load(stream)
函数。此负载应在使用块内。与通常的作用域一样,您不能引用块外的流,但是您不需要引用,因为XmlDocument
或XDocument
现在包含整个XML。如果您不想创建XDocuments或XElements,可以在与reader.ReadSubtree()的组合中使用MoveToElement()反复阅读xml。如果从顶部元素开始,则可以是整个xml字符串。我只需将每个reader.ReadSubtree()传递给一个方法,该方法确保在我处理完它后对其进行处理。尽管您绝对正确地认为对象通常不需要由于垃圾收集而被销毁,但他确实询问了MemoryStream
和XmlReader
对象。最好的做法是在使用后至少调用.Close()
,或者在使用IDisposable
对象或流时更好地使用包装,或者尝试、捕获、最终构造。@JNYRanger:是的,但如果他让他的代码变得合理,则既不会使用XmlReader也不会使用MemoryStream,因此使用
将不适用,这就是为什么我没有提到它(与我的惯例相反)。他需要在我想的某个时刻使用流来最初读取XML数据,所以这就是我提到它的原因。