XStreamingElement Klasa
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Reprezentuje elementy w drzewie XML, które obsługuje odroczone dane wyjściowe przesyłania strumieniowego.
public ref class XStreamingElement
public class XStreamingElement
type XStreamingElement = class
Public Class XStreamingElement
- Dziedziczenie
-
XStreamingElement
Przykłady
Poniższy przykład najpierw tworzy źródłowe drzewo XML. Następnie tworzy przekształcenie źródłowego drzewa XML przy użyciu polecenia XElement. Ta transformacja tworzy nowe drzewo w pamięci. Następnie tworzy przekształcenie źródłowego drzewa XML przy użyciu polecenia XStreamingElement. Ta transformacja nie wykonuje zapytania, dopóki przekształcone drzewo nie zostanie zserializowane w konsoli programu . Użycie pamięci jest mniejsze.
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)
Ten przykład generuje następujące wyniki:
<NewRoot>
<DifferentChild>3</DifferentChild>
<DifferentChild>4</DifferentChild>
<DifferentChild>5</DifferentChild>
</NewRoot>
------
<NewRoot>
<DifferentChild>3</DifferentChild>
<DifferentChild>4</DifferentChild>
<DifferentChild>5</DifferentChild>
</NewRoot>
Jednym z podejść do przetwarzania pliku tekstowego jest napisanie metody rozszerzenia, która przesyła strumieniowo plik tekstowy wiersz w czasie przy użyciu yield return
konstrukcji. Następnie można napisać zapytanie LINQ, które przetwarza plik tekstowy w leniwy sposób odroczone. Jeśli następnie użyjesz XStreamingElement elementu do przesyłania strumieniowego danych wyjściowych, możesz utworzyć przekształcenie z pliku tekstowego na XML, który używa minimalnej ilości pamięci, niezależnie od rozmiaru pliku tekstowego źródłowego.
Poniższy plik tekstowy, People.txt, jest źródłem tego przykładu.
#This is a comment
1,Tai,Yee,Writer
2,Nikolay,Grachev,Programmer
3,David,Wright,Inventor
Poniższy kod zawiera metodę rozszerzenia, która przesyła strumieniowo wiersze pliku tekstowego w sposób odroczony.
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
Ten przykład generuje następujące wyniki:
<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>
Czasami trzeba przekształcić duże pliki XML i napisać aplikację tak, aby ilość pamięci aplikacji jest przewidywalna. Jeśli spróbujesz wypełnić drzewo XML bardzo dużym plikiem XML, użycie pamięci będzie proporcjonalne do rozmiaru pliku (czyli nadmiernego). W związku z tym należy zamiast tego użyć techniki przesyłania strumieniowego.
Niektóre standardowe operatory zapytań, takie jak OrderBy, iterują swoje źródło, zbierają wszystkie dane, sortują je, a następnie w końcu dają pierwszy element w sekwencji. Pamiętaj, że jeśli używasz operatora zapytania, który zmaterializuje jego źródło przed uzyskaniem pierwszego elementu, nie zachowasz małej ilości pamięci dla aplikacji.
Nawet jeśli używasz techniki opisanej w temacie , jeśli spróbujesz utworzyć drzewo XML zawierające przekształcony dokument, użycie pamięci może być zbyt duże.
Poniższy przykład opiera się na przykładzie w temacie Jak przesyłać strumieniowo fragmenty XML z dostępem do informacji nagłówka.
W tym przykładzie użyto możliwości odroczonego XStreamingElement wykonywania w celu przesyłania strumieniowego danych wyjściowych.
Należy pamiętać, że oś niestandardowa (StreamCustomerItem
) jest specjalnie napisana tak, aby oczekiwała dokumentu z Customer
elementami , Name
i Item
, i że te elementy zostaną rozmieszczone tak, jak w poniższym dokumencie Source.xml. Bardziej niezawodna implementacja może jednak zweryfikować dokument źródłowy za pomocą XSD lub przygotować się do analizowania nieprawidłowego dokumentu.
Poniżej przedstawiono dokument źródłowy, 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>
Poniższy kod zawiera metodę, która używa elementu do XmlReader przesyłania strumieniowego kodu XML źródłowego. Używa XStreamingElement go do przesyłania strumieniowego nowego kodu 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
Ten przykład generuje następujące wyniki:
<?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>
Uwagi
Ta klasa umożliwia utworzenie drzewa XML obsługującego odroczone dane wyjściowe przesyłania strumieniowego. Ta klasa służy do tworzenia drzewa XML w bardzo podobny sposób do tworzenia drzewa XML przy użyciu polecenia XElement. Istnieje jednak podstawowa różnica. W przypadku używania zapytania LINQ do określania zawartości podczas tworzenia drzewa XML przy użyciu XElementzmiennej kwerendy jest iterowane w czasie budowy drzewa XML, a wyniki zapytania są dodawane do drzewa XML. Natomiast podczas tworzenia drzewa XML przy użyciu metody XStreamingElementodwołanie do zmiennej kwerendy jest przechowywane w drzewie XML bez iteracji. Zapytania są iterowane tylko po serializacji. Dzięki temu można tworzyć większe drzewa XML przy zachowaniu mniejszego śladu pamięci.
Jeśli przesyłasz strumieniowo ze źródła wejściowego, takiego jak plik tekstowy, możesz odczytać bardzo duży plik tekstowy i wygenerować bardzo duży dokument XML przy zachowaniu niewielkiego rozmiaru pamięci.
Innym scenariuszem jest to, że masz duże drzewo XML załadowane do pamięci i chcesz utworzyć przekształconą wersję dokumentu. Jeśli utworzysz nowy dokument przy użyciu metody XElement, po zakończeniu transformacji będziesz mieć dwa duże drzewa XML w pamięci. Jeśli jednak utworzysz nowe drzewo XML przy użyciu polecenia XStreamingElement, zestaw roboczy będzie skutecznie wycinany w połowie.
Należy pamiętać, że podczas debugowania programu, który używa XStreamingElementmetody , wyświetlając wartość obiektu powoduje wywołanie jego ToString metody. Powoduje to serializacji kodu XML. Jeśli semantyka zapytania elementu przesyłania strumieniowego jest taka, że element przesyłania strumieniowego może być przesyłany strumieniowo tylko raz, może to spowodować niepożądane zachowanie w środowisku debugowania.
Konstruktory
XStreamingElement(XName) |
Inicjuje XElement nowe wystąpienie klasy z określonego XNameelementu . |
XStreamingElement(XName, Object) |
Inicjuje XStreamingElement nowe wystąpienie klasy o określonej nazwie i zawartości. |
XStreamingElement(XName, Object[]) |
Inicjuje XStreamingElement nowe wystąpienie klasy o określonej nazwie i zawartości. |
Właściwości
Name |
Pobiera lub ustawia nazwę tego elementu przesyłania strumieniowego. |
Metody
Add(Object) |
Dodaje określoną zawartość jako elementy podrzędne do tego XStreamingElementelementu . |
Add(Object[]) |
Dodaje określoną zawartość jako elementy podrzędne do tego XStreamingElementelementu . |
Equals(Object) |
Określa, czy dany obiekt jest taki sam, jak bieżący obiekt. (Odziedziczone po Object) |
GetHashCode() |
Służy jako domyślna funkcja skrótu. (Odziedziczone po Object) |
GetType() |
Type Pobiera bieżące wystąpienie. (Odziedziczone po Object) |
MemberwiseClone() |
Tworzy płytkią kopię bieżącego Objectelementu . (Odziedziczone po Object) |
Save(Stream) |
Zwraca tę wartość XStreamingElement do określonego Streamelementu . |
Save(Stream, SaveOptions) |
Zwraca tę XStreamingElement wartość do określonego Streamelementu , opcjonalnie określając zachowanie formatowania. |
Save(String) |
Serializuj ten element przesyłania strumieniowego do pliku. |
Save(String, SaveOptions) |
Serializuj ten element przesyłania strumieniowego do pliku, opcjonalnie wyłączając formatowanie. |
Save(TextWriter) |
Serializuj ten element przesyłania strumieniowego do elementu TextWriter. |
Save(TextWriter, SaveOptions) |
Serializuj ten element przesyłania strumieniowego TextWriterdo elementu , opcjonalnie wyłączając formatowanie. |
Save(XmlWriter) |
Serializuj ten element przesyłania strumieniowego do elementu XmlWriter. |
ToString() |
Zwraca sformatowany (wcięcie) kod XML dla tego elementu przesyłania strumieniowego. |
ToString(SaveOptions) |
Zwraca kod XML dla tego elementu przesyłania strumieniowego, opcjonalnie wyłączając formatowanie. |
WriteTo(XmlWriter) |
Zapisuje ten element przesyłania strumieniowego do elementu XmlWriter. |