Overhed Overhed - 18 days ago 6
Vb.net Question

LINQ To XML Syntax for XML Element with Attributes

I'm a bit of a LINQ newbie and I was having some trouble with the following. I'm trying to perform a query using LINQ on an XML file and store the results in a list of DataClass objects that match the XML.

I've got an XML file that is defined like this:

<NewDataSet>
<NewDataTable>
<Field>Accepted ASNs</Field>
<Val>59</Val>
<Order Number="1234" ShipDate="2009/05/21" />
<Order Number="2190" ShipDate="2009/05/22" />
<Order Number="1809" ShipDate="2009/05/22" />
</NewDataTable>
<NewDataTable>
<Field>Rejected ASNs</Field>
<Val>8</Val>
<Order Number="2901" ShipDate="2009/05/21" />
<Order Number="2810" ShipDate="2009/05/24" />
<Order Number="1419" ShipDate="2009/05/25" />
</NewDataTable>
<NewDataTable>
<Field>Missing ASNs</Field>
<Val>7</Val>
<Order Number="2902" ShipDate="2009/05/19" />
<Order Number="2898" ShipDate="2009/05/20" />
<Order Number="1296" ShipDate="2009/05/22" />
</NewDataTable>
</NewDataSet>


I have created a Data class to support this XML format. What I would like to do is create a LINQ Query to grab these 3 records and store them into a List of my DataClass.

In order to support multiple Order elements, I have my class defined with a generic list of "Order" structs... It looks like this:

Public Class ASNData
Private _field As String
Private _value As String
Private _orders As List(Of Order)

Public Property Field() As String
Get
Set
End Property

Public Property Value() As String
Get
Set
End Property

Public Property Orders() As List(Of Order)
Get
Set
End Property

Structure Order
Private _number As String
Private _date As Date

Public Property Number() As String
Get
Set
End Property

Public Property ShippingDate() As Date
Get
Set
End Property
End Structure
End Class


The biggest issue I'm having is figuring out how to grab the 3 order elements and store them into my list of Order structs.

Can anyone point me in the right direction on this?

Thank you.

Answer

Here is the code for a Console application with the LINQ query you need. I had to fill in the getters and setters of your class and containing structure, but this is tested working code. To get a List(Of ASNData) just call DataTables.ToList

Of course this will work with any number of Order elements.

Using Structure Order works just fine. I would use a Class, but no need to change it for this to work.

The key part of this code is the LINQ query:

Dim DataTables = From NewDataTable In TestData...<NewDataTable> _
                 Select New ASNData With {.Field = NewDataTable.<Field>.Value, _
                                          .Value = NewDataTable.<Val>.Value, _
                                          .Orders = (From AnOrder In NewDataTable...<Order> _
                                                     Select New ASNData.Order With _
                                                            {.Number = AnOrder.@Number, _
                                                             .ShippingDate = Date.Parse(AnOrder.@ShipDate)}).ToList}

Here is the complete working console app:

Module Module1

Sub Main()
    Dim TestData = <NewDataSet>
                       <NewDataTable>
                           <Field>Accepted ASNs</Field>
                           <Val>59</Val>
                           <Order Number="1234" ShipDate="2009/05/21"/>
                           <Order Number="2190" ShipDate="2009/05/22"/>
                           <Order Number="1809" ShipDate="2009/05/22"/>
                       </NewDataTable>
                       <NewDataTable>
                           <Field>Rejected ASNs</Field>
                           <Val>8</Val>
                           <Order Number="2901" ShipDate="2009/05/21"/>
                           <Order Number="2810" ShipDate="2009/05/24"/>
                           <Order Number="1419" ShipDate="2009/05/25"/>
                       </NewDataTable>
                       <NewDataTable>
                           <Field>Missing ASNs</Field>
                           <Val>7</Val>
                           <Order Number="2902" ShipDate="2009/05/19"/>
                           <Order Number="2898" ShipDate="2009/05/20"/>
                           <Order Number="1296" ShipDate="2009/05/22"/>
                       </NewDataTable>
                   </NewDataSet>

    Dim DataTables = From NewDataTable In TestData...<NewDataTable> _
                     Select New ASNData With {.Field = NewDataTable.<Field>.Value, .Value = NewDataTable.<Val>.Value, _
                                                     .Orders = (From AnOrder In NewDataTable...<Order> _
                                                               Select New ASNData.Order With {.Number = AnOrder.@Number, .ShippingDate = Date.Parse(AnOrder.@ShipDate)}).ToList}

    Console.WriteLine(DataTables.Count)
    Console.ReadLine()


End Sub

Public Class ASNData
    Private _field As String
    Private _value As String
    Private _orders As List(Of Order)

    Public Property Field()
        Get
            Return _field
        End Get
        Set(ByVal value)
            _field = value
        End Set
    End Property

    Public Property Value() As String
        Get
            Return _value
        End Get
        Set(ByVal value As String)
            _value = value
        End Set
    End Property

    Public Property Orders() As List(Of Order)
        Get
            Return _orders
        End Get
        Set(ByVal value As List(Of Order))
            _orders = value
        End Set
    End Property

    Structure Order
        Private _number As String
        Private _date As Date

        Public Property Number() As String
            Get
                Return _number
            End Get
            Set(ByVal value As String)
                _number = value
            End Set
        End Property

        Public Property ShippingDate() As Date
            Get
                Return _date
            End Get
            Set(ByVal value As Date)
                _date = value
            End Set
        End Property
    End Structure
End Class


End Module