다음을 통해 공유


두 컬렉션을 조인하는 방법(LINQ to XML)

XSD 파일은 XML 파일에서 관계를 설정하여 요소를 조인하여 새로운 형식의 요소를 만들 수 있습니다. 이 문서에서는 요소를 조인하고 새 XML 문서를 만드는 C# 및 Visual Basic에 대한 예를 제공합니다.

XML 문서의 요소나 특성은 때때로 다른 요소나 특성을 참조할 수 있습니다. 예를 들어, XML 문서 샘플 XML 파일: 고객 및 주문에는 고객 목록과 주문 목록이 포함되어 있습니다. 모든 Customer 요소에는 CustomerID 특성이 있고 모든 Order 요소에는 CustomerID 요소가 포함되어 있습니다. Order 요소의 CustomerID 요소 값은 일치하는 CustomerID 특성 값이 있는 Customer 요소를 나타냅니다.

샘플 XSD 파일: 고객 및 주문 문서에는 Customers and orders 문서의 유효성을 검사하는 데 사용할 수 있는 XSD가 포함되어 있습니다. XSD의 xs:keyxs:keyref 기능을 사용하여 Customer 요소의 CustomerID 특성이 키임을 설정하고 키와 Order 요소의 CustomerID 요소 사이의 관계를 설정합니다.

LINQ to XML을 사용하면 join 절을 사용하여 고객 정보를 주문 정보에 조인함으로써 이 관계를 활용할 수 있습니다.

join에 대한 자세한 내용은 조인 작업(C#)조인 작업(Visual Basic)을 참조하세요.

참고 항목

조인은 선형 검색을 사용하여 수행됩니다. 검색 성능을 향상시키는 인덱스가 없습니다.

예: CustomerOrder 요소가 조인된 새 XML 문서 만들기

다음 예에서는 샘플 XML 파일: 고객 및 주문Customer 요소를 Order 요소에 조인하고 주문에 CompanyName 요소를 포함하는 새 XML 문서를 생성합니다.

이 예에서는 쿼리를 실행하기 전에 문서가 샘플 XSD 파일: 고객 및 주문의 스키마를 준수하는지 확인합니다. 이렇게 하면 조인 절이 작동하게 됩니다.

쿼리는 "K"보다 큰 CustomerID를 가진 고객의 주문만 선택합니다. 각 주문 내의 고객 정보를 포함하는 새로운 Order 요소를 투영합니다.

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

이 예제는 다음과 같은 출력을 생성합니다.

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>