将XML加载到XDocument中最快的方法是什么?当您使用XDocument.Load创建新的XDocument时,它会打开XML文件并保留本地副本,还是会不断从硬盘读取文档?如果它连续读取,是否有更快的方法来解析XML?XDocumentx=XDocument.Load("file.xml");有几个衡量指标需要考虑:线性遍历速度(例如读取/加载)按需查询速度回答直接问题:XDocument使用XmlReader通过读取每个元素并创建相应的XElement实例将文档加载到内存中(见下面的代码).因此,它应该非常快(对于大多数用途来说足够快),但在解析大型文档时可能会消耗大量内存。如果您的需求仅限于在不将文档保存在内存中的情况下可以完成的操作,则原始XmlReader是遍历的绝佳选择。它将优于其他方法,因为没有创建重要的结构,也没有与其他节点相关联(例如链接父节点和子节点)。但是,几乎没有按需查询功能;你可以对每个节点中找到的值做出反应,但你不能查询整个文档。如果需要再次查看文档,就得重新遍历整个文档。相比之下,XDocument在实例化新对象和执行基本结构任务时将花费更长的时间来遍历。它还消耗与源大小成比例的内存。作为这些折衷的交换,您将获得出色的查询功能。可以结合这些方法,如JonSkeet所提到的和此处所示:使用C#自定义迭代器和XmlReader流式传输到LINQtoXML。XDocumentLoad()的来源publicstaticXDocumentLoad(Streamstream,LoadOptionsoptions){XmlReaderSettingsxmlReaderSettings=XNode.GetXmlReaderSettings(options);X文档结果;使用(XmlReaderxmlReader=XmlReader.Create(stream,xmlReaderSettings)){result=XDocument.Load(xmlReader,options);}返回结果;}//调用...publicstaticXDocumentLoad(XmlReaderreader,LoadOptionsoptions){if(reader==null){thrownewArgumentNullException("reader");}if(reader.ReadState==ReadState.Initial){reader.Read();}XDocumentxDocument=newXDocument();if((options&LoadOptions.SetBaseUri)!=LoadOptions.None){stringbaseURI=reader.BaseURI;if(baseURI!=null&&baseURI.Length!=0){xDocument.SetBaseUri(baseURI);}}if((options&LoadOptions.SetLineInfo)!=LoadOptions.None){IXmlLineInfoxmlLineInfo=readerasIXmlLineInfo;if(xmlLineInfo!=null&&xmlLineInfo.HasLineInfo()){xDocument.SetLineInfo(xmlLineInfo.LineNumber,xmlLineInfo.LinePosition);}}if(reader.NodeType==XmlNodeType.XmlDeclaration){xDocument.Declaration=newXDeclaration(reader);}xDocument.ReadContentFrom(阅读器,选项);如果(!reader.EOF){thrownewInvalidOperationException(Res.GetString("InvalidOperation_ExpectedEndOfFile"));}if(xDocument.Root==null){thrownewInvalidOperationException(Res.GetString("InvalidOperation_MissingRoot"));}返回xDocument;}//调用...internalvoidReadContentFrom(XmlReaderr,LoadOptionso){if((o&(LoadOptions.SetBaseUri|LoadOptions.SetLineInfo))==LoadOptions.None){this.ReadContentFrom(r);返回;}if(r.ReadState!=ReadState.Interactive){thrownewInvalidOperationException(Res.GetString("InvalidOperation_ExpectedInteractive"));}XContainerxContainer=this;XNodexNode=null;命名空间缓存namespaceCache=default(命名空间缓存);命名空间缓存namespaceCache2=default(命名空间缓存e);字符串文本=((o&LoadOptions.SetBaseUri)!=LoadOptions.None)?r.BaseURI:空;IXmlLineInfoxmlLineInfo=((o&LoadOptions.SetLineInfo)!=LoadOptions.None)?(r作为IXmlLineInfo):空;while(true){stringbaseURI=r.BaseURI;switch(r.NodeType){caseXmlNodeType.Element:{XElementxElement=newXElement(namespaceCache.Get(r.NamespaceURI).GetName(r.LocalName));if(text!=null&&text!=baseURI){xElement.SetBaseUri(baseURI);}if(xmlLineInfo!=null&&xmlLineInfo.HasLineInfo()){xElement.SetLineInfo(xmlLineInfo.LineNumber,xmlLineInfo.LinePosition);}if(r.MoveToFirstAttribute()){do{XAttributexAttribute=newXAttribute(namespaceCache2.Get((r.Prefix.Length==0)?string.Empty:r.NamespaceURI).GetName(r.LocalName),r。价值);if(xmlLineInfo!=null&&xmlLineInfo.HasLineInfo()){xAttribute.SetLineInfo(xmlLineInfo.LineNumber,xmlLineInfo.LinePosition);}xElement.AppendAttributeSkipNotify(x属性);}while(r.MoveToNextAttribute());r.MoveToElement();}xContainer.AddNodeSkipNotify(xElement);如果(r.IsEmptyElement){转到IL_30A;}xContainer=xElement;if(text!=null){text=baseURI;转到IL_30A;}转到IL_30A;}caseXmlNodeType.Text:caseXmlNodeType.Whitespace:caseXmlNodeType.SignificantWhitespace:if((text!=null&&text!=baseURI)||(xmlLineInfo!=null&&xmlLineInfo.HasLineInfo())){xNode=newXText(;;r.值);转到IL_30A;}xContainer.AddStringSkipNotify(r.Value);转到IL_30A;案例XmlNodeType。CDATA:xNode=newXCData(r.Value);转到IL_30A;案例XmlNodeType。EntityReference:如果(!r。CanResolveEntity){转到Block_25;}r.ResolveEntity();转到IL_30A;案例XmlNodeType。ProcessingInstruction:xNode=newXProcessingInstruction(r.Name,r.Value);转到IL_30A;案例XmlNodeType。Comment:xNode=newXComment(r.Value);转到IL_30A;案例XmlNodeType。DocumentType:xNode=newXDocumentType(r.LocalName,r.GetAttribute("PUBLIC"),row.GetAttribute("SYSTEM"),row.Value,row.DtdInfo);转到IL_30A;caseXmlNodeType.EndElement:{if(xContainer.content==null){xContainer.content=string.Empty;}XElementxElement2=xContainer作为XElement;if(xmlLineInfo!=null&&xmlLineInfo!=null&&xmlLineInfo.HasLineInfo()){xmlLineInfo.SetEndItemLineInfo(xmlLineInfo.LineNumber,xmlLineInfo.LinePosition);}if(xContainer==this){返回;}if(text!=null&&xContainer.HasBaseUri){text=xContainer.parent.BaseUri;}xContainer=xContainer.parent;转到IL_30A;案例XmlNodeType。结束实体:转到IL_30A;}休息;IL_30A:if(xNode!=null){if(text!=null&&text!=baseURI){xNode.SetBaseUri(baseURI);}if(xmlLineInfo!=null&&xmlLineInfo.HasLineInfo()){xNode.SetLineInfo(xmlLineInfo.LineNumber,xmlLineInfo.LinePosition);}xContainer.AddNodeSkipNotify(xNode);x节点=空;}if(!r.Read()){return;}}转到IL_2E1;Block_25:扔新的InvalidOperationException(Res.GetString("InvalidOperation_UnresolvedEntityReference"));IL_2E1:thrownewInvalidOperationException(Res.GetString("InvalidOperation_UnexpectedNodeType",newobject[]{r.NodeType}));当你调用Load()然后文档的本地实例保存在内存中时,它解析传入的流(无论是来自文件还是字符串都无关紧要)因为源可以是任何东西(可以是NetworkStream,DataReader,用户输入的字符串),它无法返回并尝试再次读取数据,因为它不知道其状态(流已关闭等)。另一方面,如果你真的想要速度,XDocument不是紧固件(尽管它更容易使用),因为它需要先解析文档,然后将其保存在内存中。对于非常大的文档,使用System.Xml.XmlReader方法通常会更快,因为它可以将文档作为流读取,并且除了当前元素之外不需要保留任何内容。该基准测试显示了一些有趣的数据。我不认为它一直在阅读;关于XDocument.Load方法的事情是它使用XmlReader将XML读入XML树。因为现在你刚刚创建了一棵树,它很可能作为一棵树存储在你的记忆中,它不再经常阅读文档。它操纵树,因为它是一棵树,所以你所有的阅读和修改都会快得多。虽然它没有实现IDisposable,但它会自动处理它。以上是C#学习教程:将XML载入XDocument最快的方法是什么?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
