XStreamingElement Klass
Definition
Viktigt
En del information gäller för förhandsversionen av en produkt och kan komma att ändras avsevärt innan produkten blir allmänt tillgänglig. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, avseende informationen som visas här.
Representerar element i ett XML-träd som stöder uppskjutna strömmande utdata.
public ref class XStreamingElement
public class XStreamingElement
type XStreamingElement = class
Public Class XStreamingElement
- Arv
-
XStreamingElement
Exempel
I följande exempel skapas först ett XML-källträd. Sedan skapas en transformering av xml-källträdet med hjälp av XElement. Den här transformen skapar ett nytt träd i minnet. Sedan skapas en transformering av xml-källträdet med hjälp av XStreamingElement. Den här transformeringen kör inte frågan förrän det transformerade trädet serialiseras till konsolen. Minnesanvändningen är mindre.
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)
Det här exemplet genererar följande utdata:
<NewRoot>
<DifferentChild>3</DifferentChild>
<DifferentChild>4</DifferentChild>
<DifferentChild>5</DifferentChild>
</NewRoot>
------
<NewRoot>
<DifferentChild>3</DifferentChild>
<DifferentChild>4</DifferentChild>
<DifferentChild>5</DifferentChild>
</NewRoot>
En metod för att bearbeta en textfil är att skriva en tilläggsmetod som strömmar textfilen en rad i taget med hjälp av konstruktionen yield return . Sedan kan du skriva en LINQ-fråga som bearbetar textfilen på ett lat uppskjutet sätt. Om du sedan använder XStreamingElement för att strömma utdata kan du skapa en transformering från textfilen till XML som använder en minimal mängd minne, oavsett storleken på källtextfilen.
Följande textfil, People.txt, är källan för det här exemplet.
#This is a comment
1,Tai,Yee,Writer
2,Nikolay,Grachev,Programmer
3,David,Wright,Inventor
Följande kod innehåller en tilläggsmetod som strömmar textfilens rader på ett uppskjutet sätt.
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
Det här exemplet genererar följande utdata:
<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>
Ibland måste du transformera stora XML-filer och skriva ditt program så att programmets minnesfotavtryck är förutsägbart. Om du försöker fylla i ett XML-träd med en mycket stor XML-fil kommer minnesanvändningen att vara proportionell mot filens storlek (dvs. överdriven). Därför bör du använda en strömningsteknik i stället.
Vissa vanliga frågeoperatorer, till exempel OrderBy, itererar sin källa, samlar in alla data, sorterar dem och ger slutligen det första objektet i sekvensen. Observera att om du använder en frågeoperator som materialiserar källan innan du ger det första objektet behåller du inte ett litet minnesfotavtryck för ditt program.
Även om du använder den teknik som beskrivs i , om du försöker montera ett XML-träd som innehåller det transformerade dokumentet, kan minnesanvändningen vara för stor.
Följande exempel bygger på exemplet i Så här strömmar du XML-fragment med åtkomst till rubrikinformation.
I det här exemplet används funktionerna XStreamingElement för uppskjuten körning för att strömma utdata.
Observera att den anpassade axeln (StreamCustomerItem) är specifikt skriven så att den förväntar sig ett dokument med Customerelementen , Nameoch och Item att dessa element ordnas som i följande Source.xml dokument. En mer robust implementering skulle dock antingen validera källdokumentet med en XSD eller vara beredd att parsa ett ogiltigt dokument.
Följande är källdokumentet 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>
Följande kod innehåller en metod som använder en XmlReader för att strömma källans XML. Den använder XStreamingElement för att strömma den nya XML-koden.
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
Det här exemplet genererar följande utdata:
<?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>
Kommentarer
Med den här klassen kan du skapa ett XML-träd som stöder uppskjutna direktuppspelningsutdata. Du använder den här klassen för att skapa ett XML-träd på ett liknande sätt som när du skapar ett XML-träd med .XElement Det finns dock en grundläggande skillnad. När du använder en LINQ-fråga för att ange innehåll när du skapar ett XML-träd med , XElementitereras frågevariabeln när XML-trädet byggs och resultatet av frågan läggs till i XML-trädet. När du däremot skapar ett XML-träd med , XStreamingElementlagras en referens till frågevariabeln i XML-trädet utan att itereras. Frågor itereras endast vid serialisering. På så sätt kan du skapa större XML-träd samtidigt som du behåller ett mindre minnesavtryck.
Om du strömmar från en indatakälla, till exempel en textfil, kan du läsa en mycket stor textfil och generera ett mycket stort XML-dokument samtidigt som du behåller ett litet minnesfotavtryck.
Ett annat scenario är att du har ett stort XML-träd som har lästs in i minnet och du vill skapa en transformerad version av dokumentet. Om du skapar ett nytt dokument med , XElementhar du två stora XML-träd i minnet när omvandlingen har slutförts. Men om du skapar det nya XML-trädet med kommer XStreamingElementarbetsuppsättningen att halveras effektivt.
Observera att när du felsöker ett program som använder XStreamingElementgör visning av värdet för ett objekt att dess ToString metod anropas. Detta gör att XML-koden serialiseras. Om semantiken i din strömningselementfråga är sådan att strömningselementet bara kan strömmas en gång kan detta orsaka oönskade beteenden i felsökningsmiljön.
Konstruktorer
| Name | Description |
|---|---|
| XStreamingElement(XName, Object) |
Initierar en ny instans av XStreamingElement klassen med det angivna namnet och innehållet. |
| XStreamingElement(XName, Object[]) |
Initierar en ny instans av XStreamingElement klassen med det angivna namnet och innehållet. |
| XStreamingElement(XName) |
Initierar en ny instans av XElement klassen från den angivna XName. |
Egenskaper
| Name | Description |
|---|---|
| Name |
Hämtar eller anger namnet på det här strömmande elementet. |
Metoder
| Name | Description |
|---|---|
| Add(Object) |
Lägger till det angivna innehållet som underordnade i detta XStreamingElement. |
| Add(Object[]) |
Lägger till det angivna innehållet som underordnade i detta XStreamingElement. |
| Equals(Object) |
Avgör om det angivna objektet är lika med det aktuella objektet. (Ärvd från Object) |
| GetHashCode() |
Fungerar som standard-hash-funktion. (Ärvd från Object) |
| GetType() |
Hämtar den aktuella instansen Type . (Ärvd från Object) |
| MemberwiseClone() |
Skapar en ytlig kopia av den aktuella Object. (Ärvd från Object) |
| Save(Stream, SaveOptions) |
Matar ut detta XStreamingElement till angivet Stream, om du vill ange formateringsbeteende. |
| Save(Stream) |
Matar ut detta XStreamingElement till den angivna Stream. |
| Save(String, SaveOptions) |
Serialisera det här strömmande elementet till en fil, om du vill inaktivera formatering. |
| Save(String) |
Serialisera det här strömmande elementet till en fil. |
| Save(TextWriter, SaveOptions) |
Serialisera det här strömningselementet till en TextWriter, om du vill inaktivera formatering. |
| Save(TextWriter) |
Serialisera det här strömmande elementet till en TextWriter. |
| Save(XmlWriter) |
Serialisera det här strömmande elementet till en XmlWriter. |
| ToString() |
Returnerar den formaterade (indragna) XML:en för det här strömmande elementet. |
| ToString(SaveOptions) |
Returnerar XML för det här strömmande elementet, om du vill inaktivera formatering. |
| WriteTo(XmlWriter) |
Skriver det här strömmande elementet till en XmlWriter. |