Compartilhar 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 Query Syntax versus Method Syntax (LINQ).

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 (LINQ).

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

Attribute
Elements

Concepts

Basic Queries (LINQ to XML)

Other Resources

XML Child Axis Property
XML Attribute Axis Property
XML Value Property
Quantifier Operations (LINQ)
Projection Operators (LINQ)