To select data into XML objects, you can use syntax similar to the syntax you use to build an XML literal. You then add the special characters <%= ... %> to indicate a “hole” within the literal. Inside the hole, you replace the ellipsis with a LINQ query that extracts data from Visual Basic objects and uses them to build new XML objects.
For example, suppose the all_customers list contains Customer objects. The following code builds an XElement object that contains Customer XML elements for all of the Customer objects:
Dim x_all As XElement = _
<AllCustomers>
<%= From cust In all_customers
Select New XElement("Customer",
New XAttribute("FirstName", cust.FirstName),
New XAttribute("LastName", cust.LastName),
New XText(cust.Balance.ToString("0.00")))
%>
</AllCustomers>
The following text shows a sample of the resulting XML element:
<AllCustomers>
<Customer FirstName="Ann" LastName="Archer">100.00</Customer>
<Customer FirstName="Ben" LastName="Best">-24.54</Customer>
<Customer FirstName="Carly" LastName="Cant">62.40</Customer>
</AllCustomers>
You can have more than one hole in the XML literal. The following code uses an XML literal that contains two holes. The first uses a Where clause to select customers with non-negative balances, and the second selects customers with negative balances. It places these two groups of customers inside different sub-elements within the resulting XML.
' Separate customers with positive and negative balances.
Dim separated As XElement = _
<AllCustomers>
<PositiveBalances>
<%= From cust In x_all.Descendants("Customer")
Where CDec(cust.Value) >= 0
Order By CDec(cust.Value) Descending
Select New XElement("Customer",
New XAttribute("FirstName",
CStr(cust.Attribute("FirstName"))),
New XAttribute("LastName",
CStr(cust.Attribute("LastName"))),
New XText(cust.Value))
%>
</PositiveBalances>
<NegativeBalances>
<%= From cust In x_all.Descendants("Customer")
Where CDec(cust.Value) < 0
Order By CDec(cust.Value) Descending
Select New XElement("Customer",
New XAttribute("FirstName",
CStr(cust.Attribute("FirstName"))),
New XAttribute("LastName",
CStr(cust.Attribute("LastName"))),
New XText(cust.Value))
%>
</NegativeBalances>
</AllCustomers>
The following text shows the resulting XML element:
<AllCustomers>
<PositiveBalances>
<Customer FirstName="Dan" LastName="Dump">117.95</Customer>
<Customer FirstName="Ann" LastName="Archer">100.00</Customer>
<Customer FirstName="Carly" LastName="Cant">62.40</Customer>
</PositiveBalances>
<NegativeBalances>
<Customer FirstName="Ben" LastName="Best">-24.54</Customer>
<Customer FirstName="Frank" LastName="Fix">-150.90</Customer>
<Customer FirstName="Edna" LastName="Ever">-192.75</Customer>
</NegativeBalances>
</AllCustomers>
Example program LinqToXml, which is available for download on the book’s website, demonstrates these XML literals containing holes.