XNode.ReadFrom Method (System.Xml.Linq)

Switch View :
ScriptFree
.NET Framework Class Library
XNode.ReadFrom Method

Creates an XNode from an XmlReader.

Namespace:  System.Xml.Linq
Assembly:  System.Xml.Linq (in System.Xml.Linq.dll)
Syntax

Visual Basic
Public Shared Function ReadFrom ( _
	reader As XmlReader _
) As XNode
C#
public static XNode ReadFrom(
	XmlReader reader
)
Visual C++
public:
static XNode^ ReadFrom(
	XmlReader^ reader
)
F#
static member ReadFrom : 
        reader:XmlReader -> XNode 

Parameters

reader
Type: System.Xml.XmlReader
An XmlReader positioned at the node to read into this XNode.

Return Value

Type: System.Xml.Linq.XNode
An XNode that contains the node and its descendant nodes that were read from the reader. The runtime type of the node is determined by the node type (NodeType) of the first node encountered in the reader.
Exceptions

Exception Condition
InvalidOperationException

The XmlReader is not positioned on a recognized node type.

XmlException

The underlying XmlReader throws an exception.

Remarks

You can use this method to write a method that returns a collection of nodes, yielding each node as the node is read from the reader. This method enables you to process arbitrarily large XML files with a very small memory footprint.

The reader that you pass to this method might throw exceptions. ReadFrom does not catch all exceptions thrown by the reader; the unhandled exceptions bubble up to the code that called ReadFrom. In particular, your code should be prepared to handle XmlException.

For an example of how to stream a more complex document, see How to: Stream XML Fragments with Access to Header Information.

Certain standard query operators, such as OrderBy, iterate their source, collect all of the data, sort it, and then finally yield the first item in the sequence. If you use a query operator that materializes its source before yielding the first item, you will not retain a small memory footprint.

For an example of using LINQ to XML to transform extremely large XML documents while maintaining a small memory footprint, see How to: Perform Streaming Transform of Large XML Documents.

Examples

This example uses the following XML file, named Source.xml:

xmlLang
<?xml version="1.0" encoding="utf-8" ?> 
<Root>
  <Child Key="01">
    <GrandChild>aaa</GrandChild>
  </Child>
  <Child Key="02">
    <GrandChild>bbb</GrandChild>
  </Child>
  <Child Key="03">
    <GrandChild>ccc</GrandChild>
  </Child>
</Root>

This example creates a custom axis method that uses ReadFrom. You can query the custom axis by using a LINQ query.

Note Note

The following example uses the yield return construct of C#. Because there is no equivalent feature in Visual Basic 2008, this example is provided only in C#.

C#
class Program
{
    static IEnumerable<XElement> StreamRootChildDoc(string uri)
    {
        using (XmlReader reader = XmlReader.Create(uri))
        {
            reader.MoveToContent();
            // Parse the file and display each of the nodes.
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (reader.Name == "Child")
                        {
                            XElement el = XElement.ReadFrom(reader) as XElement;
                            if (el != null)
                                yield return el;
                        }
                        break;
                }
            }
        }
    }
    
    static void Main(string[] args)
    {
        IEnumerable<string> grandChildData =
            from el in StreamRootChildDoc("Source.xml")
            where (int)el.Attribute("Key") > 1
            select (string)el.Element("GrandChild");
    
        foreach (string str in grandChildData)
            Console.WriteLine(str);
    }
}

This example produces the following output.

bbb
ccc
Version Information

.NET Framework

Supported in: 4, 3.5

.NET Framework Client Profile

Supported in: 4, 3.5 SP1
Platforms

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
See Also

Reference

Other Resources

Community Content

Ivan Akcheurov
F# Sample Code
Yes, indeed, sample code posted in MSDN article is bad. Below is correct sample of code in F# (functionally the same as one of Peter Molchanov) $0$0 $0

let streamXmlAxis 
    matchName (reader:System.IO.TextReader) =
    seq {
        use xmlReader = XmlReader.Create(reader)
        xmlReader.MoveToContent() |> ignore
        while not xmlReader.EOF do
            match xmlReader.NodeType with
            | XmlNodeType.Element when xmlReader.Name = matchName -> yield (XElement.ReadFrom(xmlReader) :?> XElement)
            | _ -> xmlReader.Read() |> ignore
    }
$0
$0 $0$0 $0

pmolchanov
Bad Sample Code
If the XML is not pretty printed (XML all on a single line), this sample code shown above will not work as expected. The provided sample code will produce: $0$0 $0ccc$0 $0$0 $0 $0 $0Sample code with problem corrected:$0 $0$0 $0 $0 $0 class Program
    {
        static IEnumerable<XElement> StreamRootChildDoc(string uri)
        {
            using (XmlReader reader = XmlReader.Create(uri))
            {
                reader.MoveToContent();
                // Parse the file and display each of the nodes.
                while (!reader.EOF)
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            if (reader.Name == "Child")
                            {
                                XElement el = XElement.ReadFrom(reader) as XElement;
                                if (el != null)
                                    yield return el;
                            }
                            else
                            {
                                reader.Read();
                            }
                            break;
                        default:
                            reader.Read();
                            break;
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            IEnumerable<string> grandChildData =
                from el in StreamRootChildDoc("XMLFile.xml")
                where (int)el.Attribute("Key") > 1
                select (string)el.Element("GrandChild");

            foreach (string str in grandChildData)
                Console.WriteLine(str);
        }
    }$0 $0 $0$0 $0 $0$0 $0