Parsing XML with LINQ To XML and VB.NET

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • PsychoCoder
    Recognized Expert Contributor
    • Jul 2010
    • 465

    Parsing XML with LINQ To XML and VB.NET

    I'm working on parsing XML returned from a web service call. This is a sample of the returned XML (the actually result is much larger):

    Code:
    ?xml version="1.0" encoding="utf-16"?>
    <HotelPropertyDescriptionRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" TimeStamp="2013-12-30T18:49:36" Version="1.14.1">
      <Success xmlns="http://webservices.sabre.com/sabreXML/2003/07" />
      <RoomStay xmlns="http://webservices.sabre.com/sabreXML/2003/07">
        <RoomRates>
          <RoomRate GuaranteeSurchargeRequired="G" IATACharacteristicIdentification="BGGO00" IATAProductIdentification="BLOOMBERG" RPH="001">
            <AdditionalInfo>
              <CancelPolicy Numeric="06" />
              <Commission NonCommission="true">NON COMMISSIONABLE</Commission>
              <Text>BLOOMBERG LP, 0.0 KM, INCLUDES BREAKFAST, INTERNET, WIFI, SEE</Text>
              <Text>RATE RULES DELUXE ROOM, GUEST ROOM, 1 KING OR 2 TWIN/SINGLE BE</Text>
            </AdditionalInfo>
            <Rates>
              <Rate Amount="66.600" CurrencyCode="KWD">
                <AdditionalGuestAmounts>
                  <AdditionalGuestAmount MaxExtraPersonsAllowed="0">
                    <Charges ExtraPerson="0" />
                  </AdditionalGuestAmount>
                </AdditionalGuestAmounts>
                <HotelTotalPricing Amount="76.590">
                  <Disclaimer>INCLUDES TAXES AND SURCHARGES</Disclaimer>
                  <TotalSurcharges Amount="9.990" />
                </HotelTotalPricing>
              </Rate>
            </Rates>
          </RoomRate>
    ...
    I am attempting to parse it into this class

    Code:
    Namespace Classes.Models
        Public Class RoomRate
            Public Property Rate() As String
            Public Property Surcharge() As String
            Public Property TotalPrice() As String
            Public Property CurrencyCode() As String
            Public Property CancellationPolicy() As String
            Public Property Disclaimer() As String
            Public Property Text() As List(Of String)
            Public Property Commission() As String
            Public Property GuaranteeSurchargeRequired() As String
            Public Property IATACharacteristicIdentification() As String
            Public Property IATAProductIdentification() As String
            Public Property RPH() As String
        End Class
    End Namespace
    I have this function which should accomplish this:

    Code:
    Public Function ParseRates() As IEnumerable(Of RoomRate)
    	Try
    		Return From el As XElement In _xDoc...<RoomRate>
    					Select New RoomRate With { _
    					   .GuaranteeSurchargeRequired = el.@GuaranteeSurchargeRequired, _
    					   .IATACharacteristicIdentification = el.@IATACharacteristicIdentification, _
    					   .IATAProductIdentification = el.@IATAProductIdentification, _
    					   .RPH = el.@RPH, _
    					   .CancellationPolicy = el...<AdditionalInfo>...<CancellationPolicy>.@Numeric, _
    					   .Commission = el...<AdditionalInfo>...<Commission>.@NonCommission, _
    					   .Rate = el...<Rates>...<Rate>.@Amount, _
    					   .CurrencyCode = el...<Rates>...<Rate>.@CurrencyCode, _
    					   .TotalPrice = el...<Rates>...<Rate>...<HotelTotalPricing>.@Amount, _
    					   .Surcharge = el...<Rates>...<Rate>...<TotalSurchjarges>.@Amount}
    	Catch ex As Exception
    		ErrorMessage = ex.Message
    		Return Nothing
    	End Try
    End Function
    Then when I try and test it with this test page (page load event):

    Code:
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim parse As New ParseSabre(Server.MapPath("~/XML/SabreSample.xml"))
        Dim rates As IEnumerable(Of RoomRate)()
    
        rates = parse.ParseRates()
    
        'If rates = Nothing Then
    
        'End If
        For Each rate As RoomRate In rates
            Response.Write(rate.GuaranteeSurchargeRequired)
            Response.Write(rate.IATACharacteristicIdentification)
            Response.Write(rate.IATAProductIdentification)
            Response.Write(rate.RPH)
            Response.Write(rate.CancellationPolicy)
            Response.Write(rate.Commission)
            Response.Write(rate.Rate)
            Response.Write(rate.CurrencyCode)
            Response.Write(rate.TotalPrice)
            Response.Write(rate.Surcharge)
            Response.Write(vbNewLine)
        Next
    End Sub
    I get the following error

    Unable to cast object of type 'WhereSelectEnu merableIterator `2[System.Xml.Linq .XElement,Lodgx .Classes.Models .RoomRate]' to type 'System.Collect ions.Generic.IE numerable`1[Lodgx.Classes.M odels.RoomRate][]'.

    Can someone tell me
    1. Is my code for parsing going to accomplish what I'm looking for?
    2. How can I get rid of that error so I can continue to test this?
  • PsychoCoder
    Recognized Expert Contributor
    • Jul 2010
    • 465

    #2
    I have changed my code to look like so. I get no error but no values are returned:

    Code:
    For Each n As XElement In _xDoc.Descendants("RoomRate")
        rate = New RoomRate()
        rate.GuaranteeSurchargeRequired = n.Attribute("GuaranteeSurchargeRequired").Value
        rate.IATACharacteristicIdentification = n.Attribute("IATACharacteristicIdentification").Value
        rate.IATAProductIdentification = n.Attribute("IATAProductIdentification")
        
        _rates.Add(rate)
    Next

    Comment

    Working...