How to: Write Queries with Complex Filtering

Sometimes you want to write LINQ to XML queries with complex filters. For example, you might have to find all elements that have a child element with a particular name and value. This topic gives an example of writing a query with complex filtering.

Example

This example shows how to find all PurchaseOrder elements that have a child Address element that has a Type attribute equal to "Shipping" and a child State element equal to "NY". It uses a nested query in the Where clause, and the Any operator returns true if the collection has any elements in it. For information about using method-based query syntax, see LINQ Query Syntax versus Method Syntax (C#).

This example uses the following XML document: Sample XML File: Multiple Purchase Orders (LINQ to XML).

For more information about the Any operator, see Quantifier Operations.

XElement root = XElement.Load("PurchaseOrders.xml");
IEnumerable<XElement> purchaseOrders =
    from el in root.Elements("PurchaseOrder")
    where 
        (from add in el.Elements("Address")
        where
            (string)add.Attribute("Type") == "Shipping" &&
            (string)add.Element("State") == "NY"
        select add)
        .Any()
    select el;
foreach (XElement el in purchaseOrders)
    Console.WriteLine((string)el.Attribute("PurchaseOrderNumber"));
Dim root As XElement = XElement.Load("PurchaseOrders.xml")
Dim purchaseOrders As IEnumerable(Of XElement) = _
    From el In root.<PurchaseOrder> _
    Where _
        (From add In el.<Address> _
        Where _
             add.@Type = "Shipping" And _
             add.<State>.Value = "NY" _
        Select add) _
    .Any() _
    Select el
For Each el As XElement In purchaseOrders
    Console.WriteLine(el.@PurchaseOrderNumber)
Next

This code produces the following output:

99505

The following example shows the same query for XML that is in a namespace. For more information, see Working with XML Namespaces.

This example uses the following XML document: Sample XML File: Multiple Purchase Orders in a Namespace.

XElement root = XElement.Load("PurchaseOrdersInNamespace.xml");
XNamespace aw = "https://www.adventure-works.com";
IEnumerable<XElement> purchaseOrders =
    from el in root.Elements(aw + "PurchaseOrder")
    where
        (from add in el.Elements(aw + "Address")
         where
             (string)add.Attribute(aw + "Type") == "Shipping" &&
             (string)add.Element(aw + "State") == "NY"
         select add)
        .Any()
    select el;
foreach (XElement el in purchaseOrders)
    Console.WriteLine((string)el.Attribute(aw + "PurchaseOrderNumber"));
Imports <xmlns:aw='https://www.adventure-works.com'>

Module Module1
    Sub Main()
        Dim root As XElement = XElement.Load("PurchaseOrdersInNamespace.xml")
        Dim purchaseOrders As IEnumerable(Of XElement) = _
            From el In root.<aw:PurchaseOrder> _
            Where _
                (From add In el.<aw:Address> _
                Where _
                     add.@aw:Type = "Shipping" And _
                     add.<aw:State>.Value = "NY" _
                Select add) _
            .Any() _
            Select el
        For Each el As XElement In purchaseOrders
            Console.WriteLine(el.@aw:PurchaseOrderNumber)
        Next
    End Sub
End Module

This code produces the following output:

99505

See Also

Concepts

Basic Queries (LINQ to XML)

Quantifier Operations

Projection Operations

Reference

XML Child Axis Property

XML Attribute Axis Property

XML Value Property

Attribute

Elements