XStreamingElement クラス
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
遅延ストリーミング出力をサポートする XML ツリー内の要素を表します。
public ref class XStreamingElement
public class XStreamingElement
type XStreamingElement = class
Public Class XStreamingElement
- 継承
-
XStreamingElement
例
次の例では、最初にソース XML ツリーを作成します。 次に、 XElementを使用してソース XML ツリーの変換を作成します。 この変換により、メモリ内に新しいツリーが作成されます。 次に、 XStreamingElementを使用してソース XML ツリーの変換を作成します。 変換されたツリーがコンソールにシリアル化されるまで、この変換はクエリを実行しません。 メモリ使用量が少なくなります。
XElement srcTree = new XElement("Root",
new XElement("Child", 1),
new XElement("Child", 2),
new XElement("Child", 3),
new XElement("Child", 4),
new XElement("Child", 5)
);
XElement dstTree1 = new XElement("NewRoot",
from el in srcTree.Elements()
where (int)el >= 3
select new XElement("DifferentChild", (int)el)
);
XStreamingElement dstTree2 = new XStreamingElement("NewRoot",
from el in srcTree.Elements()
where (int)el >= 3
select new XElement("DifferentChild", (int)el)
);
Console.WriteLine(dstTree1);
Console.WriteLine("------");
Console.WriteLine(dstTree2);
Dim srcTree As XElement = _
<Root>
<Child>1</Child>
<Child>2</Child>
<Child>3</Child>
<Child>4</Child>
<Child>5</Child>
</Root>
Dim dstTree1 As XElement = _
<NewRoot>
<%= From el In srcTree.Elements _
Where (el.Value >= 3) _
Select <DifferentChild><%= el.Value %></DifferentChild> %>
</NewRoot>
Dim dstTree2 As XStreamingElement = New XStreamingElement("NewRoot", _
From el In srcTree.Elements _
Where el.Value >= 3 _
Select <DifferentChild><%= el.Value %></DifferentChild> _
)
Console.WriteLine(dstTree1)
Console.WriteLine("------")
Console.WriteLine(dstTree2)
この例を実行すると、次の出力が生成されます。
<NewRoot>
<DifferentChild>3</DifferentChild>
<DifferentChild>4</DifferentChild>
<DifferentChild>5</DifferentChild>
</NewRoot>
------
<NewRoot>
<DifferentChild>3</DifferentChild>
<DifferentChild>4</DifferentChild>
<DifferentChild>5</DifferentChild>
</NewRoot>
テキスト ファイルを処理する方法の 1 つは、 yield return コンストラクトを使用してテキスト ファイルを一度に 1 行ずつストリーム配信する拡張メソッドを記述することです。 その後、遅延遅延形式でテキスト ファイルを処理する LINQ クエリを記述できます。 その後、 XStreamingElement を使用して出力をストリーミングする場合は、ソース テキスト ファイルのサイズに関係なく、最小限のメモリを使用する XML にテキスト ファイルから変換を作成できます。
次のテキスト ファイル People.txtは、この例のソースです。
#This is a comment
1,Tai,Yee,Writer
2,Nikolay,Grachev,Programmer
3,David,Wright,Inventor
次のコードには、テキスト ファイルの行を遅延形式でストリーミングする拡張メソッドが含まれています。
public static class StreamReaderSequence
{
public static IEnumerable<string> Lines(this StreamReader source)
{
String line;
if (source == null)
throw new ArgumentNullException("source");
while ((line = source.ReadLine()) != null)
{
yield return line;
}
}
}
class Program
{
static void Main(string[] args)
{
StreamReader sr = new StreamReader("People.txt");
XStreamingElement xmlTree = new XStreamingElement("Root",
from line in sr.Lines()
let items = line.Split(',')
where !line.StartsWith("#")
select new XElement("Person",
new XAttribute("ID", items[0]),
new XElement("First", items[1]),
new XElement("Last", items[2]),
new XElement("Occupation", items[3])
)
);
Console.WriteLine(xmlTree);
sr.Close();
}
}
Module StreamReaderSequence
<Runtime.CompilerServices.Extension>
Public Iterator Function Lines(source As IO.StreamReader) As IEnumerable(Of String)
If source Is Nothing Then Throw New ArgumentNullException("source")
Dim line As String = source.ReadLine()
While (line <> Nothing)
Yield line
line = source.ReadLine()
End While
End Function
End Module
Module Module1
Sub Main()
Dim sr As New IO.StreamReader("People.txt")
Dim xmlTree As New XStreamingElement("Root",
From line In sr.Lines()
Let items = line.Split(","c)
Where Not line.StartsWith("#")
Select <Person ID=<%= items(0) %>>
<First><%= items(1) %></First>
<Last><%= items(2) %></Last>
<Occupation><%= items(3) %></Occupation>
</Person>)
Console.WriteLine(xmlTree)
sr.Close()
End Sub
End Module
この例を実行すると、次の出力が生成されます。
<Root>
<Person ID="1">
<First>Tai</First>
<Last>Yee</Last>
<Occupation>Writer</Occupation>
</Person>
<Person ID="2">
<First>Nikolay</First>
<Last>Grachev</Last>
<Occupation>Programmer</Occupation>
</Person>
<Person ID="3">
<First>David</First>
<Last>Wright</Last>
<Occupation>Inventor</Occupation>
</Person>
</Root>
場合によっては、大きな XML ファイルを変換し、アプリケーションのメモリ占有領域を予測できるようにアプリケーションを記述する必要があります。 XML ツリーに非常に大きな XML ファイルを設定しようとすると、メモリ使用量はファイルのサイズ (つまり過剰) に比例します。 そのため、代わりにストリーミング手法を使用する必要があります。
OrderByなどの特定の標準クエリ演算子は、ソースを反復処理し、すべてのデータを収集して並べ替え、最後にシーケンスの最初の項目を生成します。 最初の項目を生成する前にソースを具体化するクエリ演算子を使用する場合、アプリケーションのメモリ占有領域は小さく保持されないことに注意してください。
で説明されている手法を使用する場合でも、変換されたドキュメントを含む XML ツリーをアセンブルしようとすると、メモリ使用量が大きすぎる可能性があります。
次の例は、「 ヘッダー情報にアクセスして XML フラグメントをストリーミングする方法」の例に基づいています。
この例では、 XStreamingElement の遅延実行機能を使用して出力をストリーミングします。
カスタム軸 (StreamCustomerItem) は、 Customer、 Name、および Item 要素を含むドキュメントを想定し、これらの要素が次の Source.xml ドキュメントのように配置されるように、特に記述されていることに注意してください。 ただし、より堅牢な実装では、XSD を使用してソース ドキュメントを検証するか、無効なドキュメントを解析する準備をします。
ソース ドキュメントの Source.xmlを次に示します。
<?xml version="1.0" encoding="utf-8" ?>
<Root>
<Customer>
<Name>A. Datum Corporation</Name>
<Item>
<Key>0001</Key>
</Item>
<Item>
<Key>0002</Key>
</Item>
<Item>
<Key>0003</Key>
</Item>
<Item>
<Key>0004</Key>
</Item>
</Customer>
<Customer>
<Name>Fabrikam, Inc.</Name>
<Item>
<Key>0005</Key>
</Item>
<Item>
<Key>0006</Key>
</Item>
<Item>
<Key>0007</Key>
</Item>
<Item>
<Key>0008</Key>
</Item>
</Customer>
<Customer>
<Name>Southridge Video</Name>
<Item>
<Key>0009</Key>
</Item>
<Item>
<Key>0010</Key>
</Item>
</Customer>
</Root>
次のコードには、 XmlReader を使用してソース XML をストリーミングするメソッドが含まれています。 XStreamingElementを使用して新しい XML をストリーミングします。
static IEnumerable<XElement> StreamCustomerItem(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
XElement name = null;
XElement item = null;
reader.MoveToContent();
// Parse the file, save header information when encountered, and yield the
// Item XElement objects as they are created.
// loop through Customer elements
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Customer")
{
// move to Name element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "Name")
{
name = XElement.ReadFrom(reader) as XElement;
break;
}
}
// loop through Item elements
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.EndElement)
break;
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Item")
{
item = XElement.ReadFrom(reader) as XElement;
if (item != null)
{
XElement tempRoot = new XElement("Root",
new XElement(name)
);
tempRoot.Add(item);
yield return item;
}
}
}
}
}
}
}
static void Main(string[] args)
{
XStreamingElement root = new XStreamingElement("Root",
from el in StreamCustomerItem("Source.xml")
select new XElement("Item",
new XElement("Customer", (string)el.Parent.Element("Name")),
new XElement(el.Element("Key"))
)
);
root.Save("Test.xml");
Console.WriteLine(File.ReadAllText("Test.xml"));
}
Iterator Function StreamCustomerItem(uri As String) As IEnumerable(Of XElement)
Dim name As XElement = Nothing
Dim item As XElement = Nothing
Dim reader As XmlReader = XmlReader.Create(uri)
reader.MoveToContent()
' Parse the file, save header information when encountered, and yield the
' Item XElement objects as they are created.
' Loop through Customer elements.
While (reader.Read())
If (reader.NodeType = XmlNodeType.Element And reader.Name = "Customer") Then
While (reader.Read())
' Move to Name element
If (reader.NodeType = XmlNodeType.Element And reader.Name = "Name") Then
name = CType(XElement.ReadFrom(reader), XElement)
Exit While
End If
End While
' Loop through Item elements
While (reader.Read())
If (reader.NodeType = XmlNodeType.EndElement) Then
Exit While
End If
If (reader.NodeType = XmlNodeType.Element And reader.Name = "Item") Then
item = CType(XElement.ReadFrom(reader), XElement)
If (Not (item Is Nothing)) Then
Dim tempRoot = New XElement("Root",
New XElement(name)
)
tempRoot.Add(item)
Yield item
End If
End If
End While
End If
End While
reader.Close()
End Function
Sub Main()
Dim root As New XStreamingElement("Root",
From el In StreamCustomerItem("c:\trash\Source.xml")
Select New XElement("Item",
New XElement("Customer", CStr(el.Parent.Element("Name"))),
New XElement(el.Element("Key"))))
root.Save("c:\trash\Test.xml")
Console.WriteLine(System.IO.File.ReadAllText("c:\trash\Test.xml"))
End Sub
この例を実行すると、次の出力が生成されます。
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0001</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0002</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0003</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0004</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0005</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0006</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0007</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0008</Key>
</Item>
<Item>
<Customer>Southridge Video</Customer>
<Key>0009</Key>
</Item>
<Item>
<Customer>Southridge Video</Customer>
<Key>0010</Key>
</Item>
</Root>
注釈
このクラスを使用すると、遅延ストリーミング出力をサポートする XML ツリーを作成できます。 このクラスを使用すると、 XElementを使用して XML ツリーを作成するのとよく似た方法で XML ツリーを作成できます。 ただし、根本的な違いがあります。 LINQ クエリを使用して、 XElementを使用して XML ツリーを作成するときにコンテンツを指定すると、XML ツリーの構築時にクエリ変数が反復処理され、クエリの結果が XML ツリーに追加されます。 これに対し、 XStreamingElementを使用して XML ツリーを作成すると、クエリ変数への参照が反復処理されずに XML ツリーに格納されます。 クエリは、シリアル化時にのみ反復処理されます。 これにより、メモリ占有領域を小さく維持しながら、より大きな XML ツリーを作成できます。
テキスト ファイルなどの入力ソースからストリーミングする場合は、非常に大きなテキスト ファイルを読み取り、メモリ占有領域を小さくしながら非常に大きな XML ドキュメントを生成できます。
もう 1 つのシナリオは、メモリに読み込まれた大きな XML ツリーがあり、変換されたバージョンのドキュメントを作成することです。 XElementを使用して新しいドキュメントを作成すると、変換の完了時に 2 つの大きな XML ツリーがメモリに格納されます。 ただし、 XStreamingElementを使用して新しい XML ツリーを作成すると、ワーキング セットは実質的に半分にカットされます。
XStreamingElementを使用するプログラムをデバッグする場合、オブジェクトの値を表示すると、そのToStringメソッドが呼び出されることに注意してください。 これにより、XML がシリアル化されます。 ストリーミング要素クエリのセマンティクスがストリーミング要素を 1 回しかストリーミングできない場合、デバッグ エクスペリエンスで望ましくない動作が発生する可能性があります。
コンストラクター
| 名前 | 説明 |
|---|---|
| XStreamingElement(XName, Object) |
指定した名前とコンテンツを使用して、 XStreamingElement クラスの新しいインスタンスを初期化します。 |
| XStreamingElement(XName, Object[]) |
指定した名前とコンテンツを使用して、 XStreamingElement クラスの新しいインスタンスを初期化します。 |
| XStreamingElement(XName) |
プロパティ
| 名前 | 説明 |
|---|---|
| Name |
このストリーミング要素の名前を取得または設定します。 |
メソッド
| 名前 | 説明 |
|---|---|
| Add(Object) |
指定したコンテンツを子としてこの XStreamingElementに追加します。 |
| Add(Object[]) |
指定したコンテンツを子としてこの XStreamingElementに追加します。 |
| Equals(Object) |
指定したオブジェクトが現在のオブジェクトと等しいかどうかを判断します。 (継承元 Object) |
| GetHashCode() |
既定のハッシュ関数として機能します。 (継承元 Object) |
| GetType() |
現在のインスタンスの Type を取得します。 (継承元 Object) |
| MemberwiseClone() |
現在の Objectの簡易コピーを作成します。 (継承元 Object) |
| Save(Stream, SaveOptions) |
この XStreamingElement を指定した Streamに出力し、必要に応じて書式設定の動作を指定します。 |
| Save(Stream) |
この XStreamingElement を指定した Streamに出力します。 |
| Save(String, SaveOptions) |
このストリーミング要素をファイルにシリアル化し、必要に応じて書式設定を無効にします。 |
| Save(String) |
このストリーミング要素をファイルにシリアル化します。 |
| Save(TextWriter, SaveOptions) |
このストリーミング要素を TextWriterにシリアル化し、必要に応じて書式設定を無効にします。 |
| Save(TextWriter) |
このストリーミング要素を TextWriterにシリアル化します。 |
| Save(XmlWriter) |
このストリーミング要素を XmlWriterにシリアル化します。 |
| ToString() |
このストリーミング要素の書式設定された (インデントされた) XML を返します。 |
| ToString(SaveOptions) |
必要に応じて書式設定を無効にして、このストリーミング要素の XML を返します。 |
| WriteTo(XmlWriter) |
このストリーミング要素を XmlWriterに書き込みます。 |