XStreamingElement Třída
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Představuje prvky ve stromu XML, který podporuje výstup odloženého streamování.
public ref class XStreamingElement
public class XStreamingElement
type XStreamingElement = class
Public Class XStreamingElement
- Dědičnost
-
XStreamingElement
Příklady
Následující příklad nejprve vytvoří zdrojový strom XML. Pak vytvoří transformaci zdrojového stromu XML pomocí XElement. Tato transformace vytvoří v paměti nový strom. Pak vytvoří transformaci zdrojového stromu XML pomocí XStreamingElement. Tato transformace nespustí dotaz, dokud se transformovaný strom serializuje do konzoly. Využití paměti je menší.
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)
Tento příklad vytvoří následující výstup:
<NewRoot>
<DifferentChild>3</DifferentChild>
<DifferentChild>4</DifferentChild>
<DifferentChild>5</DifferentChild>
</NewRoot>
------
<NewRoot>
<DifferentChild>3</DifferentChild>
<DifferentChild>4</DifferentChild>
<DifferentChild>5</DifferentChild>
</NewRoot>
Jedním z přístupů ke zpracování textového souboru je zápis rozšiřující metody, která streamuje textový soubor řádek najednou pomocí konstruktoru yield return
. Pak můžete napsat dotaz LINQ, který zpracovává textový soubor opožděným odloženým způsobem. Pokud pak použijete XStreamingElement k streamování výstupu, můžete vytvořit transformaci z textového souboru na XML, která používá minimální velikost paměti bez ohledu na velikost zdrojového textového souboru.
Následující textový soubor People.txt je zdrojem tohoto příkladu.
#This is a comment
1,Tai,Yee,Writer
2,Nikolay,Grachev,Programmer
3,David,Wright,Inventor
Následující kód obsahuje rozšiřující metodu, která streamuje řádky textového souboru odloženým způsobem.
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
Tento příklad vytvoří následující výstup:
<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>
Někdy musíte transformovat velké soubory XML a zapsat aplikaci tak, aby nároky na paměť aplikace byly předvídatelné. Pokud se pokusíte naplnit strom XML velmi velkým souborem XML, bude využití paměti úměrné velikosti souboru (to znamená nadměrné). Proto byste měli místo toho použít metodu streamování.
Některé standardní operátory dotazů, jako OrderByje například iterace jejich zdroje, shromáždí všechna data, seřadí je a nakonec vyvolají první položku v posloupnosti. Všimněte si, že pokud použijete operátor dotazu, který materializuje jeho zdroj před vydáním první položky, neuchováváte pro aplikaci malou paměťovou stopu.
I když použijete techniku popsanou v tématu , pokud se pokusíte sestavit strom XML, který obsahuje transformovaný dokument, může být využití paměti příliš velké.
Následující příklad vychází z příkladu v části Jak streamovat fragmenty XML s přístupem k informacím hlavičky.
V tomto příkladu se k streamování výstupu XStreamingElement používají možnosti odloženého spuštění.
Všimněte si, že vlastní osa (StreamCustomerItem
) je speciálně napsaná tak, aby očekávala dokument, který obsahuje Customer
, Name
a Item
prvky a že tyto prvky budou uspořádány jako v následujícím Source.xml dokumentu. Robustnější implementace by však buď ověřila zdrojový dokument pomocí XSD, nebo by byla připravena analyzovat neplatný dokument.
Tady je zdrojový dokument 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>
Následující kód obsahuje metodu, která používá XmlReader k streamování zdrojového XML. Používá XStreamingElement se k streamování nového 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
Tento příklad vytvoří následující výstup:
<?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>
Poznámky
Tato třída umožňuje vytvořit strom XML, který podporuje odložený výstup streamování. Tuto třídu použijete k vytvoření stromu XML velmi podobným způsobem jako vytvoření stromu XML pomocí XElement. Existuje však zásadní rozdíl. Pokud použijete dotaz LINQ k určení obsahu při vytváření stromu XML pomocí XElement, proměnná dotazu se iterated v době vytvoření stromu XML a výsledky dotazu se přidají do stromu XML. Naproti tomu při vytváření stromu XML pomocí XStreamingElement, odkaz na proměnnou dotazu je uložen ve stromu XML bez iterated. Dotazy jsou iterated pouze při serializaci. Díky tomu můžete vytvářet větší stromy XML při zachování menší paměti.
Pokud streamujete ze vstupního zdroje, například z textového souboru, můžete přečíst velmi velký textový soubor a vygenerovat velmi velký dokument XML a zachovat tak malou paměťovou stopu.
Dalším scénářem je, že máte velký strom XML, který byl načten do paměti, a chcete vytvořit transformovanou verzi dokumentu. Pokud vytvoříte nový dokument pomocí XElement, po dokončení transformace budete mít v paměti dva velké stromy XML. Pokud však vytvoříte nový strom XML pomocí XStreamingElement, pracovní sada se bude efektivně snížit na polovinu.
Všimněte si, že při ladění programu, který používá XStreamingElement, zobrazení hodnoty objektu způsobí, že jeho ToString metoda bude volána. To způsobí serializaci XML. Pokud je sémantika dotazu prvku streamování taková, že element streamování lze streamovat pouze jednou, může to způsobit nežádoucí chování v prostředí ladění.
Konstruktory
XStreamingElement(XName) | |
XStreamingElement(XName, Object) |
Inicializuje novou instanci XStreamingElement třídy se zadaným názvem a obsahem. |
XStreamingElement(XName, Object[]) |
Inicializuje novou instanci XStreamingElement třídy se zadaným názvem a obsahem. |
Vlastnosti
Name |
Získá nebo nastaví název tohoto streamovacího prvku. |
Metody
Add(Object) |
Přidá zadaný obsah jako podřízené položky do tohoto XStreamingElementsouboru . |
Add(Object[]) |
Přidá zadaný obsah jako podřízené položky do tohoto XStreamingElementsouboru . |
Equals(Object) |
Určí, zda se zadaný objekt rovná aktuálnímu objektu. (Zděděno od Object) |
GetHashCode() |
Slouží jako výchozí funkce hash. (Zděděno od Object) |
GetType() |
Type Získá aktuální instanci. (Zděděno od Object) |
MemberwiseClone() |
Vytvoří použádnou kopii aktuálního souboru Object. (Zděděno od Object) |
Save(Stream) |
Výstupem je XStreamingElement zadaný Stream. |
Save(Stream, SaveOptions) |
Vypíše toto XStreamingElement do zadaného Stream, volitelně určení chování formátování. |
Save(String) |
Serializovat tento streamovací prvek do souboru. |
Save(String, SaveOptions) |
Serializace tohoto streamovacího prvku do souboru, volitelně zakázání formátování. |
Save(TextWriter) |
Serializace tohoto streamovacího prvku na TextWriter. |
Save(TextWriter, SaveOptions) |
Serializace tohoto streamovacího prvku na TextWriter, volitelně zakázání formátování. |
Save(XmlWriter) |
Serializovat tento streamovací prvek na XmlWriter. |
ToString() |
Vrátí formátovaný (odsazený) XML pro tento prvek streamování. |
ToString(SaveOptions) |
Vrátí xml pro tento element streamování, volitelně zakázání formátování. |
WriteTo(XmlWriter) |
Zapíše tento streamovací prvek do objektu XmlWriter. |