Freigeben über


Vorgehensweise: Verknüpfen zweier Auflistungen (C#) (LINQ to XML)

Ein Element oder Attribut in einem XML-Dokument kann mitunter auf ein anderes Element oder Attribut verweisen. So enthält z. B. das XML-Dokument in Kunden ('Customers') und Aufträge ('Orders') eine Liste von Kunden und eine Liste von Aufträgen. Jedes Customer-Element enthält ein CustomerID-Attribut. Jedes Order-Element enthält ein CustomerID-Element. Das CustomerID-Element eines Auftrags verweist auf das CustomerID-Attribut eines Kunden.

Das Thema XSD-Beispieldatei: Kunden ('Customers') und Aufträge ('Orders') enthält ein XSD-Schema, das zum Validieren dieses Dokuments verwendet werden kann. Mit den Funktionen xs:key und xs:keyref des XSD-Schemas wird geprüft, ob das CustomerID-Attribut des Customer-Elements ein Schlüssel ist. Außerdem wird damit eine Beziehung zwischen dem CustomerID-Element in jedem Order-Element und dem CustomerID-Attribut in jedem Customer-Element hergestellt.

Mit LINQ to XML können Sie diese Beziehung durch Verwenden der join-Klausel nutzen.

Da es keinen Index gibt, führt eine solche Verknüpfung zu einer schlechten Laufzeitleistung.

Ausführlichere Informationen zu join finden Sie unter Verknüpfungsvorgänge.

Beispiel

Das folgende Beispiel verknüpft die Customer-Elemente mit den Order-Elementen und generiert ein neues XML-Dokument, das das CompanyName-Element der Aufträge enthält.

Vor dem Ausführen der Abfrage überprüft das Beispiel, ob das Dokument dem Schema in XSD-Beispieldatei: Kunden ('Customers') und Aufträge ('Orders') entspricht. Auf diese Weise wird sichergestellt, dass die JOIN-Klausel immer funktioniert.

Diese Abfrage ruft zuerst alle Customer-Elemente ab und verknüpft sie dann mit den Order-Elementen. Sie 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.

In diesem Beispiel wird das XML-Dokument in XML-Beispieldatei: Kunden ('Customers') und Aufträge ('Orders') (LINQ to XML) verwendet.

In diesem Beispiel wird das XSD-Schema in XSD-Beispieldatei: Kunden ('Customers') und Aufträge ('Orders') verwendet.

Beachten Sie, dass diese Art von Verknüpfungen zu Leistungseinbußen führt. Joins (Verknüpfungen) werden über eine lineare Suche ausgeführt. Es gibt keine Hashtabellen oder Indizes, die die Geschwindigkeit erhöhen könnten.

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

Dieser Code 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>

Siehe auch

Konzepte

Erweiterte Abfragetechniken (LINQ to XML)