Ansluta två samlingar (LINQ till XML)
En XSD-fil kan upprätta relationer i en XML-fil för att möjliggöra sammanfogning av element för att skapa nya typer av element. Den här artikeln innehåller ett exempel för C# och Visual Basic som kopplar samman element och skapar ett nytt XML-dokument.
Ett element eller attribut i ett XML-dokument kan ibland referera till ett annat element eller attribut. Xml-dokumentExempel-XML-fil : Kunder och beställningar innehåller till exempel en lista över kunder och en lista över beställningar. Varje Customer
element har ett CustomerID
attribut och varje Order
element innehåller ett CustomerID
element. Elementvärdet CustomerID
i ett Order
element refererar till elementet Customer
som har ett matchande CustomerID
attributvärde.
Artikeln XSD-exempelfil: Kunder och beställningar innehåller en XSD som kan användas för att verifiera Customers and orders
dokumentet. Den använder xs:key
funktionerna och xs:keyref
i XSD för att fastställa att CustomerID
elementets Customer
attribut är en nyckel och för att upprätta en relation mellan nyckeln och elementet CustomerID
i elementen Order
.
Med LINQ till XML kan du dra nytta av den här relationen med hjälp join
av satsen för att koppla kundinformation till beställningsinformation.
Mer detaljerad information om join
finns i Join Operations (C#) and Join Operations (Visual Basic).
Kommentar
Kopplingar görs med linjära sökningar. Det finns inga index för att öka sökprestandan.
Exempel: Skapa ett nytt XML-dokument som har Customer
och Order
element anslutna
I följande exempel genereras ett nytt XML-dokument som kopplar elementen i Customer
XML-exempelfilen: Kunder och beställningar till elementen Order
och innehåller elementet CompanyName
i beställningarna.
Innan du kör frågan verifierar exemplet att dokumentet uppfyller schemat i XSD-exempelfilen: Kunder och beställningar. Detta säkerställer att kopplingssatsen fungerar.
Frågan väljer endast order för kunder med större CustomerID
än "K". Den projicerar nya Order
element som innehåller kundinformationen i varje beställning.
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
Det här exemplet genererar följande utdata:
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>