Verbinden von zwei Sammlungen (LINQ to XML)
Eine XSD-Datei kann Beziehungen in einer XML-Datei einrichten, um das Verknüpfen von Elementen zum Erstellen neuer Elementtypen zu ermöglichen. Dieser Artikel enthält ein Beispiel für C# und Visual Basic, das Elemente verknüpft und ein neues XML-Dokument erstellt.
Ein Element oder Attribut in einem XML-Dokument kann mitunter auf ein anderes Element oder Attribut verweisen. Zum Beispiel XML-Dokument Beispiel XML-Datei: Kunden und Aufträge enthält eine Liste von Kunden und eine Liste von Aufträgen. Jedes Customer
-Element verfügt über ein CustomerID
-Attribut, und jedes Order
-Element enthält ein CustomerID
-Element. Der CustomerID
-Elementwert in einem Order
-Element bezieht sich auf das Customer
-Element, das über einen übereinstimmenden CustomerID
-Attributwert verfügt.
Das Thema Beispiel-XSD-Datei: Kunden und Aufträge enthält ein XSD-Schema, das zum Validieren des Customers and orders
-Dokuments verwendet werden kann. Es verwendet die xs:key
- und xs:keyref
-Funktionen von XSD, um festzustellen, dass das CustomerID
-Attribut des Customer
-Elements ein Schlüssel ist, und um eine Beziehung zwischen dem Schlüssel und dem CustomerID
-Element der Order
-Elemente herzustellen.
Mit LINQ to XML können Sie diese Beziehung nutzen, indem Sie die join
-Klausel verwenden, um Kundeninformationen mit Bestellinformationen zu verbinden.
Ausführlichere Informationen zu join
, finden Sie unter Join-Vorgänge (C#) und Joinvorgänge (Visual Basic).
Hinweis
Verknüpfungen werden mithilfe linearer Suchvorgänge durchgeführt. Es gibt keine Indizes, um die Suchleistung zu steigern.
Beispiel: Erstellen eines neuen XML-Dokuments mit verknüpften Customer
- und Order
-Elementen
Im folgenden Beispiel wird ein neues XML-Dokument generiert, das die Customer
-Elemente der XML-Beispieldatei: Kunden und Aufträge mit den Order
-Elementen verknüpft und das CompanyName
-Element in die Bestellungen einschließt.
Vor dem Ausführen der Abfrage überprüft das Beispiel, ob das Dokument dem Schema in Beispiel-XSD-Datei: Kunden und Bestellungen entspricht. Auf diese Weise wird sichergestellt, dass die join-Klausel immer funktioniert.
Die Anfrage wählt dabei nur die Aufträge der Kunden aus, deren CustomerID
größer als „K“ ist. Anschließend projiziert die Abfrage ein neues Order
-Element, das die Kundeninformationen in den einzelnen Aufträgen enthält.
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
Dieses Beispiel erzeugt die folgende Ausgabe:
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>