Twee verzamelingen koppelen (LINQ aan XML)
Een XSD-bestand kan relaties tot stand brengen in een XML-bestand, zodat elementen kunnen worden samengevoegd om nieuwe typen elementen te maken. Dit artikel bevat een voorbeeld voor C# en Visual Basic waarmee elementen worden samengevoegd en een nieuw XML-document wordt gemaakt.
Een element of kenmerk in een XML-document kan soms verwijzen naar een ander element of kenmerk. Xml-document voorbeeld-XML-bestand: Klanten en orders bevatten bijvoorbeeld een lijst met klanten en een lijst met orders. Elk Customer
element heeft een CustomerID
kenmerk en elk Order
element bevat een CustomerID
element. De CustomerID
elementwaarde in een Order
element verwijst naar het Customer
element met een overeenkomende CustomerID
kenmerkwaarde.
Het voorbeeld-XSD-bestand : Klanten en orders bevatten een XSD die kan worden gebruikt om het Customers and orders
document te valideren. Het maakt gebruik van de xs:key
en xs:keyref
functies van XSD om vast te stellen dat het CustomerID
kenmerk van het Customer
element een sleutel is en om een relatie tot stand te brengen tussen de sleutel en het CustomerID
element van de Order
elementen.
Met LINQ naar XML kunt u profiteren van deze relatie door de join
component te gebruiken om klantgegevens samen te voegen om informatie te bestellen.
Zie Join Operations (C#) en Join Operations (Visual Basic) voor meer informatie overjoin
.
Notitie
Joins worden uitgevoerd met behulp van lineaire zoekopdrachten. Er zijn geen indexen om de zoekprestaties te verbeteren.
Voorbeeld: Een nieuw XML-document maken waaraan elementen zijn Customer
Order
toegevoegd
In het volgende voorbeeld wordt een nieuw XML-document gegenereerd dat de elementen van het Customer
XML-voorbeeldbestand koppelt: Klanten en orders aan de Order
elementen en bevat het CompanyName
element in de orders.
Voordat u de query uitvoert, wordt in het voorbeeld gevalideerd dat het document voldoet aan het schema in het XSD-voorbeeldbestand: Klanten en orders. Dit zorgt ervoor dat de join-component werkt.
De query selecteert alleen de orders voor klanten met een CustomerID
hogere waarde dan K. Het project projecteert nieuwe Order
elementen die de klantgegevens binnen elke order bevatten.
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", "CustomersOrders.xsd");
Console.Write("Attempting to validate, ");
XDocument custOrdDoc = XDocument.Load("CustomersOrders.xml");
bool errors = false;
custOrdDoc.Validate(schemas, (o, e) =>
{
Console.WriteLine("{0}", e.Message);
errors = true;
});
Console.WriteLine("custOrdDoc {0}", errors ? "did not validate" : "validated");
if (!errors)
{
// Join customers and orders, and create a new XML document with
// a different shape.
// The new document contains orders only for customers with a
// CustomerID > 'K'
XElement custOrd = custOrdDoc.Element("Root");
XElement newCustOrd = new XElement("Root",
from c in custOrd.Element("Customers").Elements("Customer")
join o in custOrd.Element("Orders").Elements("Order")
on (string)c.Attribute("CustomerID") equals
(string)o.Element("CustomerID")
where ((string)c.Attribute("CustomerID")).CompareTo("K") > 0
select new XElement("Order",
new XElement("CustomerID", (string)c.Attribute("CustomerID")),
new XElement("CompanyName", (string)c.Element("CompanyName")),
new XElement("ContactName", (string)c.Element("ContactName")),
new XElement("EmployeeID", (string)o.Element("EmployeeID")),
new XElement("OrderDate", (DateTime)o.Element("OrderDate"))
)
);
Console.WriteLine(newCustOrd);
}
Public Class Program
Public Shared errors As Boolean = False
Public Shared Function LamValidEvent(ByVal o As Object, _
ByVal e As ValidationEventArgs) As Boolean
Console.WriteLine("{0}", e.Message)
errors = True
End Function
Shared Sub Main()
Dim schemas As New XmlSchemaSet()
schemas.Add("", "CustomersOrders.xsd")
Console.Write("Attempting to validate, ")
Dim custOrdDoc As XDocument = XDocument.Load("CustomersOrders.xml")
custOrdDoc.Validate(schemas, Function(o, e) LamValidEvent(0, e))
If errors Then
Console.WriteLine("custOrdDoc did not validate")
Else
Console.WriteLine("custOrdDoc validated")
End If
If Not errors Then
'Join customers and orders, and create a new XML document with
' a different shape.
'The new document contains orders only for customers with a
' CustomerID > 'K'.
Dim custOrd As XElement = custOrdDoc.<Root>.FirstOrDefault
Dim newCustOrd As XElement = _
<Root>
<%= From c In custOrd.<Customers>.<Customer> _
Join o In custOrd.<Orders>.<Order> _
On c.@CustomerID Equals o.<CustomerID>.Value _
Where c.@CustomerID.CompareTo("K") > 0 _
Select _
<Order>
<CustomerID><%= c.@CustomerID %></CustomerID>
<%= c.<CompanyName> %>
<%= c.<ContactName> %>
<%= o.<EmployeeID> %>
<%= o.<OrderDate> %>
</Order> _
%>
</Root>
Console.WriteLine(newCustOrd)
End If
End Sub
End Class
In dit voorbeeld wordt de volgende uitvoer gegenereerd:
Attempting to validate, custOrdDoc validated
<Root>
<Order>
<CustomerID>LAZYK</CustomerID>
<CompanyName>Lazy K Kountry Store</CompanyName>
<ContactName>John Steel</ContactName>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-03-21T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LAZYK</CustomerID>
<CompanyName>Lazy K Kountry Store</CompanyName>
<ContactName>John Steel</ContactName>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-05-22T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<EmployeeID>1</EmployeeID>
<OrderDate>1997-06-25T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<EmployeeID>8</EmployeeID>
<OrderDate>1997-10-27T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-11-10T00:00:00</OrderDate>
</Order>
<Order>
<CustomerID>LETSS</CustomerID>
<CompanyName>Let's Stop N Shop</CompanyName>
<ContactName>Jaime Yorres</ContactName>
<EmployeeID>4</EmployeeID>
<OrderDate>1998-02-12T00:00:00</OrderDate>
</Order>
</Root>