Cara menggabungkan dua koleksi (LINQ ke XML)
File XSD dapat menjalin hubungan dalam file XML, untuk memungkinkan bergabungnya elemen untuk membuat jenis elemen baru. Artikel ini memberikan contoh untuk C# dan Visual Basic yang menggabungkan elemen dan membuat dokumen XML baru.
Elemen atau atribut dalam dokumen XML terkadang dapat merujuk ke elemen atau atribut lain. Misalnya, dokumen XML File XML sampel: Pelanggan dan pesanan berisi daftar pelanggan dan daftar pesanan. Setiap elemen Customer
memiliki atribut CustomerID
, dan setiap elemen Order
berisi elemen CustomerID
. Nilai elemen CustomerID
dalam elemen Order
mengacu pada elemen Customer
yang memiliki nilai atribut CustomerID
yang cocok.
Artikel file XSD Sampel: Pelanggan dan pesanan berisi XSD yang dapat digunakan untuk memvalidasi dokumen Customers and orders
. Ini menggunakan fitur xs:key
dan xs:keyref
XSD untuk menetapkan bahwa atribut CustomerID
dari elemen Customer
adalah kunci, dan untuk membangun hubungan antara kunci dan elemen CustomerID
dari elemen Order
.
Dengan LINQ ke XML, Anda dapat memanfaatkan hubungan ini dengan menggunakan klausul join
untuk menggabungkan informasi pelanggan dengan informasi pemesanan.
Untuk informasi selengkapnya tentang join
, lihat Operasi Penggabungan (C#) dan Operasi Penggabungan (Visual Basic).
Catatan
Penggabungan dilakukan menggunakan pencarian linier. Tidak ada indeks untuk meningkatkan performa pencarian.
Contoh: Membuat dokumen XML baru yang memiliki penggabungan elemen Customer
dan Order
Contoh berikut menghasilkan dokumen XML baru yang menggabungkan elemen Customer
dari File XML sampel: Pelanggan dan pesanan ke elemen Order
, dan menyertakan elemen CompanyName
dalam pesanan.
Sebelum menjalankan kueri, contoh memvalidasi bahwa dokumen mematuhi skema dalam File XSD sampel: Pelanggan dan pesanan. Ini memastikan bahwa klausa penggabungan akan berfungsi.
Kueri hanya memilih pesanan untuk pelanggan dengan CustomerID
lebih besar dari "K". Ini memproyeksikan elemen Order
baru yang berisi informasi pelanggan dalam setiap pesanan.
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
Contoh ini menghasilkan output berikut:
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>