Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将XML加载到XDocument中的最快方法是什么?_C#_.net_Xml_Linq To Xml - Fatal编程技术网

C# 将XML加载到XDocument中的最快方法是什么?

C# 将XML加载到XDocument中的最快方法是什么?,c#,.net,xml,linq-to-xml,C#,.net,Xml,Linq To Xml,使用XDocument.Load创建新的XDocument时,它是打开XML文件并保留本地副本,还是从硬盘连续读取文档?如果它连续读取,有没有更快的方法来解析XML XDocument x = XDocument.Load("file.xml"); 有两种测量方法需要考虑: 线性遍历速度(例如读取/加载) 按需查询速度 要回答眼前的问题:XDocument使用XmlReader通过读取每个元素并创建相应的XElement实例将文档加载到内存中(请参见下面的代码)。因此,它应该相当快(对于大多数

使用
XDocument.Load
创建新的
XDocument
时,它是打开XML文件并保留本地副本,还是从硬盘连续读取文档?如果它连续读取,有没有更快的方法来解析XML

XDocument x = XDocument.Load("file.xml");

有两种测量方法需要考虑:

  • 线性遍历速度(例如读取/加载)
  • 按需查询速度
  • 要回答眼前的问题:
    XDocument
    使用
    XmlReader
    通过读取每个元素并创建相应的
    XElement
    实例将文档加载到内存中(请参见下面的代码)。因此,它应该相当快(对于大多数目的来说足够快),但在解析大型文档时可能会消耗大量内存

    如果您的需求仅限于无需将文档保留在内存中即可完成的内容,那么原始
    XmlReader
    是遍历的最佳选择。它的性能优于其他方法,因为与其他节点(例如链接父节点和子节点)的关系不会创建或解析重要结构。然而,按需查询能力几乎不存在;您可以对每个节点中的值作出反应,但不能作为一个整体查询文档。如果需要再次查看文档,则必须再次遍历整个文档

    相比之下,
    XDocument
    将需要更长的时间来遍历,因为它实例化新对象并执行基本的结构化任务。它还将消耗与源大小成比例的内存。作为这些权衡的交换,您将获得出色的查询能力

    可以将这些方法结合起来,如下所示:

    XDocument Load()的源文件


    我不认为它一直在读;
    XDocument.Load
    方法的优点在于它使用
    XmlReader
    将XML读入XML树。因为现在你刚刚创建了一棵树,它很可能以树的形式存储在你的内存中,它不再不断地读取文档。它操纵着树,因为它是一棵树,所以你的阅读和修改速度要快得多。虽然它没有实现IDisposable,但它会被自动处理。

    当您调用
    Load()
    并在内存中保留文档的本地实例时,它将解析传入流(不管是来自文件还是字符串)。由于源可以是任何内容(可以是NetworkStream、DataReader、用户输入的字符串),因此无法返回并再次尝试读取数据,因为它不知道数据的状态(正在关闭的流等)


    另一方面,如果您真的想提高速度,那么XDocument不是fastets(尽管它更容易使用),因为它需要首先解析文档,然后将其保留在内存中。如果使用的方法处理非常大的文档,通常速度要快得多,因为它可以将文档作为流读取,并且不需要保留除当前元素以外的任何内容。这显示了一些有趣的数据。

    谢谢,这真的很有帮助。我在XNA中使用了它,我想我需要减少调用XDocument.Load的次数,因为我在每个对象中都使用了它,而且我不需要。更新了同一篇文章的新链接。@Karl JohanSjögren链接仍然没有使用。还没有,但它又死掉了。我花了整整一分钟才在谷歌上找到这篇文章,所以我再次更新了链接。
    public static XDocument Load(Stream stream, LoadOptions options)
    {
        XmlReaderSettings xmlReaderSettings = XNode.GetXmlReaderSettings(options);
        XDocument result;
        using (XmlReader xmlReader = XmlReader.Create(stream, xmlReaderSettings))
        {
            result = XDocument.Load(xmlReader, options);
        }
        return result;
    }
    
    // which calls...
    
    public static XDocument Load(XmlReader reader, LoadOptions options)
    {
        if (reader == null)
        {
            throw new ArgumentNullException("reader");
        }
        if (reader.ReadState == ReadState.Initial)
        {
            reader.Read();
        }
        XDocument xDocument = new XDocument();
        if ((options & LoadOptions.SetBaseUri) != LoadOptions.None)
        {
            string baseURI = reader.BaseURI;
            if (baseURI != null && baseURI.Length != 0)
            {
                xDocument.SetBaseUri(baseURI);
            }
        }
        if ((options & LoadOptions.SetLineInfo) != LoadOptions.None)
        {
            IXmlLineInfo xmlLineInfo = reader as IXmlLineInfo;
            if (xmlLineInfo != null && xmlLineInfo.HasLineInfo())
            {
                xDocument.SetLineInfo(xmlLineInfo.LineNumber, xmlLineInfo.LinePosition);
            }
        }
        if (reader.NodeType == XmlNodeType.XmlDeclaration)
        {
            xDocument.Declaration = new XDeclaration(reader);
        }
        xDocument.ReadContentFrom(reader, options);
        if (!reader.EOF)
        {
            throw new InvalidOperationException(Res.GetString("InvalidOperation_ExpectedEndOfFile"));
        }
        if (xDocument.Root == null)
        {
            throw new InvalidOperationException(Res.GetString("InvalidOperation_MissingRoot"));
        }
        return xDocument;
    }
    
    // which calls...
    
    internal void ReadContentFrom(XmlReader r, LoadOptions o)
    {
        if ((o & (LoadOptions.SetBaseUri | LoadOptions.SetLineInfo)) == LoadOptions.None)
        {
            this.ReadContentFrom(r);
            return;
        }
        if (r.ReadState != ReadState.Interactive)
        {
            throw new InvalidOperationException(Res.GetString("InvalidOperation_ExpectedInteractive"));
        }
        XContainer xContainer = this;
        XNode xNode = null;
        NamespaceCache namespaceCache = default(NamespaceCache);
        NamespaceCache namespaceCache2 = default(NamespaceCache);
        string text = ((o & LoadOptions.SetBaseUri) != LoadOptions.None) ? r.BaseURI : null;
        IXmlLineInfo xmlLineInfo = ((o & LoadOptions.SetLineInfo) != LoadOptions.None) ? (r as IXmlLineInfo) : null;
        while (true)
        {
            string baseURI = r.BaseURI;
            switch (r.NodeType)
            {
            case XmlNodeType.Element:
            {
                XElement xElement = new XElement(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
                    {
                        XAttribute xAttribute = new XAttribute(namespaceCache2.Get((r.Prefix.Length == 0) ? string.Empty : r.NamespaceURI).GetName(r.LocalName), r.Value);
                        if (xmlLineInfo != null && xmlLineInfo.HasLineInfo())
                        {
                            xAttribute.SetLineInfo(xmlLineInfo.LineNumber, xmlLineInfo.LinePosition);
                        }
                        xElement.AppendAttributeSkipNotify(xAttribute);
                    }
                    while (r.MoveToNextAttribute());
                    r.MoveToElement();
                }
                xContainer.AddNodeSkipNotify(xElement);
                if (r.IsEmptyElement)
                {
                    goto IL_30A;
                }
                xContainer = xElement;
                if (text != null)
                {
                    text = baseURI;
                    goto IL_30A;
                }
                goto IL_30A;
            }
            case XmlNodeType.Text:
            case XmlNodeType.Whitespace:
            case XmlNodeType.SignificantWhitespace:
                if ((text != null && text != baseURI) || (xmlLineInfo != null && xmlLineInfo.HasLineInfo()))
                {
                    xNode = new XText(r.Value);
                    goto IL_30A;
                }
                xContainer.AddStringSkipNotify(r.Value);
                goto IL_30A;
            case XmlNodeType.CDATA:
                xNode = new XCData(r.Value);
                goto IL_30A;
            case XmlNodeType.EntityReference:
                if (!r.CanResolveEntity)
                {
                    goto Block_25;
                }
                r.ResolveEntity();
                goto IL_30A;
            case XmlNodeType.ProcessingInstruction:
                xNode = new XProcessingInstruction(r.Name, r.Value);
                goto IL_30A;
            case XmlNodeType.Comment:
                xNode = new XComment(r.Value);
                goto IL_30A;
            case XmlNodeType.DocumentType:
                xNode = new XDocumentType(r.LocalName, r.GetAttribute("PUBLIC"), r.GetAttribute("SYSTEM"), r.Value, r.DtdInfo);
                goto IL_30A;
            case XmlNodeType.EndElement:
            {
                if (xContainer.content == null)
                {
                    xContainer.content = string.Empty;
                }
                XElement xElement2 = xContainer as XElement;
                if (xElement2 != null && xmlLineInfo != null && xmlLineInfo.HasLineInfo())
                {
                    xElement2.SetEndElementLineInfo(xmlLineInfo.LineNumber, xmlLineInfo.LinePosition);
                }
                if (xContainer == this)
                {
                    return;
                }
                if (text != null && xContainer.HasBaseUri)
                {
                    text = xContainer.parent.BaseUri;
                }
                xContainer = xContainer.parent;
                goto IL_30A;
            }
            case XmlNodeType.EndEntity:
                goto IL_30A;
            }
            break;
            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);
                xNode = null;
            }
            if (!r.Read())
            {
                return;
            }
        }
        goto IL_2E1;
        Block_25:
        throw new InvalidOperationException(Res.GetString("InvalidOperation_UnresolvedEntityReference"));
        IL_2E1:
        throw new InvalidOperationException(Res.GetString("InvalidOperation_UnexpectedNodeType", new object[]
        {
            r.NodeType
        }));
    }