次の方法で共有


方法 : XmlReader から XML フラグメントをストリーム出力する

更新 : November 2007

大きな XML ファイルを処理する必要があるときに、XML ツリー全体をメモリに読み込むことができない場合があります。このトピックでは、XmlReader を使用してフラグメントをストリーム出力する方法について説明します。

XmlReader を使用して XElement オブジェクトを読み取るための最も効果的な方法の 1 つは、カスタムの軸メソッドを独自に記述することです。一般に軸メソッドは、このトピックの例で示すように、XElementIEnumerable<T> などのコレクションを返します。カスタムの軸メソッドでは、ReadFrom メソッドを呼び出して XML フラグメントを作成した後に、yield return を使用してコレクションを返します。これにより、カスタムの軸メソッドに遅延実行セマンティクスが付加されます。

XmlReader オブジェクトから XML ツリーを作成する場合は、XmlReader を要素に配置する必要があります。ReadFrom メソッドは、要素の終了タグを読み取るまで制御を戻しません。

部分ツリーを作成する場合は、XmlReader をインスタンス化し、XElement ツリーに変換するノード上にリーダーを配置し、XElement オブジェクトを作成します。

トピック「方法 : ヘッダー情報にアクセスして XML フラグメントをストリーム出力する」には、より複雑なドキュメントをストリーム出力する方法とその例が示されています。

トピック「方法: 大きな XML ドキュメントのストリーミング変換を実行する」には、LINQ to XML を使用して、メモリ使用量を低く抑えながら非常に大きな XML ドキュメントを変換する例が示されています。

使用例

次の例では、カスタムの軸メソッドを作成します。このメソッドに対してクエリを実行するには、LINQ クエリを使用します。カスタムの軸メソッド StreamRootChildDoc は、Child 要素が繰り返し出現するドキュメントを読み取るために特に設計されたメソッドです。

メモ :

次の例では、C# の yield return 構造を使用します。Visual Basic 2008 には類似した機能がないため、この例は C# のみを対象としています。

static IEnumerable<XElement> StreamRootChildDoc(StringReader stringReader)
{
    using (XmlReader reader = XmlReader.Create(stringReader))
    {
        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)
{
    string markup = @"<Root>
      <Child Key=""01"">
        <GrandChild>aaa</GrandChild>
      </Child>
      <Child Key=""02"">
        <GrandChild>bbb</GrandChild>
      </Child>
      <Child Key=""03"">
        <GrandChild>ccc</GrandChild>
      </Child>
    </Root>";

    IEnumerable<string> grandChildData =
        from el in StreamRootChildDoc(new StringReader(markup))
        where (int)el.Attribute("Key") > 1
        select (string)el.Element("GrandChild");

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

この例では次の出力が生成されます。

bbb
ccc

この例のソース ドキュメントは、非常に小さなドキュメントです。ただし、何百万の Child 要素があっても、この例で使用されるメモリは非常に少量です。

参照

概念

XML の解析