Share via


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

Reference

XML Child Axis Property (Visual Basic)

XML Attribute Axis Property (Visual Basic)

XML Value Property (Visual Basic)

Attribute

Elements

Concepts

Basic Queries (LINQ to XML)

Quantifier Operations

Projection Operations