-1

I am getting the SOAP xml response like this:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
    <ns2:MultiAvailabilityResponse xmlns:ns2="http://www.derbysoft.com/doorway" Status="Successful" Token="187be58c62c2f2515b5d78ee">
        <ns2:Availabilities>
            <ns2:Availability CurrencyCode="USD" HotelCode="HY-CHIRC">
                <ns2:GuestCount AdultCount="1" ChildCount="0"/>
                <ns2:RoomTypes>
                    <ns2:RoomType RoomTypeCode="JRSQ" RoomTypeName="JR SUITE 2 QUEEN BEDS">
                        <ns2:RoomTypeDescription>Rest in sublime comfort on one of two queen signature Hyatt Grand Beds®, fitted with fine linens, down blanket and plump pillows.</ns2:RoomTypeDescription>
                    </ns2:RoomType>
                    <ns2:RoomType RoomTypeCode="CLBD" RoomTypeName="REG CLUB 2 DOUBLE BEDS">
                        <ns2:RoomTypeDescription>one King or two double-sized Hyatt Grand Beds, fitted with luxurious linens, a down blanket and plush pillows</ns2:RoomTypeDescription>
                    </ns2:RoomType>
                    <ns2:RoomType RoomTypeCode="VW2Q" RoomTypeName="PREMIUM VW 2 QEN">
                        <ns2:RoomTypeDescription>Relax and unwind in our sophisticated downtown Chicago guestrooms with city, river and lake views</ns2:RoomTypeDescription>
                    </ns2:RoomType>

                </ns2:RoomTypes>

                <ns2:RoomRates>
                    <ns2:RoomRate RatePlanCode="49584IPRTF" RoomTypeCode="JRSQ">
                        <ns2:Rates>
                            <ns2:Rate AmountAfterTax="523.348" AmountBeforeTax="449.650" EffectiveDate="2016-04-28" ExpireDate="2016-04-29"/>
                        </ns2:Rates>
                        <ns2:Fees>
                            <ns2:Fee ChargeType="Tax" Percent="16.390" Type="Exclusive"/>
                        </ns2:Fees>
                    </ns2:RoomRate>
                    <ns2:RoomRate RatePlanCode="49584IPRTF" RoomTypeCode="CLBD">
                        <ns2:Rates>
                            <ns2:Rate AmountAfterTax="350.218" AmountBeforeTax="300.900" EffectiveDate="2016-04-28" ExpireDate="2016-04-29"/>
                        </ns2:Rates>
                        <ns2:Fees>
                            <ns2:Fee ChargeType="Tax" Percent="16.390" Type="Exclusive"/>
                        </ns2:Fees>
                    </ns2:RoomRate>
                    <ns2:RoomRate RatePlanCode="49584IPRTF" RoomTypeCode="VW2Q">
                        <ns2:Rates>
                            <ns2:Rate AmountAfterTax="305.699" AmountBeforeTax="262.650" EffectiveDate="2016-04-28" ExpireDate="2016-04-29"/>
                        </ns2:Rates>
                        <ns2:Fees>
                            <ns2:Fee ChargeType="Tax" Percent="16.390" Type="Exclusive"/>
                        </ns2:Fees>
                    </ns2:RoomRate>

                </ns2:RoomRates>
            </ns2:Availability>
        </ns2:Availabilities>
    </ns2:MultiAvailabilityResponse>
</SOAP-ENV:Body>

I am parsing it using xmltodict library. Now, I just want some elements from this response to use in my app. The elements, I want are: RatePlanCode, RoomTypeCode, RoomTypeName, AmountBeforeTax. Also, I want to sort the response based on AmountBeforeTax and get the result in the form of dictionary, my_dict = {'roomlist': [{'RoomTypeCode':value, 'RatePlanCode': vlaue, 'RoomTypeName': value, 'AmountBeforeTax': value }]}.

I didn't work with SOAP xml's and banging my head since morning. Any help would be appreciated. Thanks!

Raman Balyan
  • 983
  • 2
  • 16
  • 32

1 Answers1

1

I don't think that xmltodict is the best choices for this. Perhaps some other SOAP parser is a better choice.

Having said that, here is an xmltodict-based program that parses the SOAP sample you've given above.

# encoding: utf-8
import xmltodict


def listify(obj):
    if isinstance(obj, list):
        return obj
    return [obj]

def get_details(soap):
    # Parse the SOAP
    soap = xmltodict.parse(soap, process_namespaces=True)

    # Deal with namespaces
    env = 'http://schemas.xmlsoap.org/soap/envelope/:'
    doorway = 'http://www.derbysoft.com/doorway:'

    # Everything we care about is in "Availability"
    availability = listify(
        soap[env+'Envelope']
            [env+'Body']
            [doorway+'MultiAvailabilityResponse']
            [doorway+'Availabilities']
            [doorway+'Availability'])

    # Intermediate data structure to hold room names
    names = {
        roomtype['@RoomTypeCode']: roomtype['@RoomTypeName']
        for _availability in availability
        for roomtype in listify(_availability
            [doorway+'RoomTypes']
            [doorway+'RoomType'])
    }

    # Result!
    return {
        'roomlist': sorted([
            {
                'RoomTypeCode': roomrate['@RoomTypeCode'],
                'RatePlanCode': roomrate['@RatePlanCode'],
                'RoomTypeName': names[roomrate['@RoomTypeCode']],
                'AmountBeforeTax': rate['@AmountBeforeTax'],
            }
            for _availability in availability
            for roomrate in listify(_availability
                [doorway+'RoomRates']
                [doorway+'RoomRate'])
            for rate in listify(roomrate
                [doorway+'Rates']
                [doorway+'Rate'])],
            key=lambda x:float(x['AmountBeforeTax']))
    }


if __name__ == "__main__":
    soap = '''
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
        <ns2:MultiAvailabilityResponse xmlns:ns2="http://www.derbysoft.com/doorway" Status="Successful" Token="187be58c62c2f2515b5d78ee">
            <ns2:Availabilities>
                <ns2:Availability CurrencyCode="USD" HotelCode="HY-CHIRC">
                    <ns2:GuestCount AdultCount="1" ChildCount="0"/>
                    <ns2:RoomTypes>
                        <ns2:RoomType RoomTypeCode="JRSQ" RoomTypeName="JR SUITE 2 QUEEN BEDS">
                            <ns2:RoomTypeDescription>Rest in sublime comfort on one of two queen signature Hyatt Grand Beds®, fitted with fine linens, down blanket and plump pillows.</ns2:RoomTypeDescription>
                        </ns2:RoomType>
                        <ns2:RoomType RoomTypeCode="CLBD" RoomTypeName="REG CLUB 2 DOUBLE BEDS">
                            <ns2:RoomTypeDescription>one King or two double-sized Hyatt Grand Beds, fitted with luxurious linens, a down blanket and plush pillows</ns2:RoomTypeDescription>
                        </ns2:RoomType>
                        <ns2:RoomType RoomTypeCode="VW2Q" RoomTypeName="PREMIUM VW 2 QEN">
                            <ns2:RoomTypeDescription>Relax and unwind in our sophisticated downtown Chicago guestrooms with city, river and lake views</ns2:RoomTypeDescription>
                        </ns2:RoomType>

                    </ns2:RoomTypes>

                    <ns2:RoomRates>
                        <ns2:RoomRate RatePlanCode="49584IPRTF" RoomTypeCode="JRSQ">
                            <ns2:Rates>
                                <ns2:Rate AmountAfterTax="523.348" AmountBeforeTax="449.650" EffectiveDate="2016-04-28" ExpireDate="2016-04-29"/>
                            </ns2:Rates>
                            <ns2:Fees>
                                <ns2:Fee ChargeType="Tax" Percent="16.390" Type="Exclusive"/>
                            </ns2:Fees>
                        </ns2:RoomRate>
                        <ns2:RoomRate RatePlanCode="49584IPRTF" RoomTypeCode="CLBD">
                            <ns2:Rates>
                                <ns2:Rate AmountAfterTax="350.218" AmountBeforeTax="300.900" EffectiveDate="2016-04-28" ExpireDate="2016-04-29"/>
                            </ns2:Rates>
                            <ns2:Fees>
                                <ns2:Fee ChargeType="Tax" Percent="16.390" Type="Exclusive"/>
                            </ns2:Fees>
                        </ns2:RoomRate>
                        <ns2:RoomRate RatePlanCode="49584IPRTF" RoomTypeCode="VW2Q">
                            <ns2:Rates>
                                <ns2:Rate AmountAfterTax="305.699" AmountBeforeTax="262.650" EffectiveDate="2016-04-28" ExpireDate="2016-04-29"/>
                            </ns2:Rates>
                            <ns2:Fees>
                                <ns2:Fee ChargeType="Tax" Percent="16.390" Type="Exclusive"/>
                            </ns2:Fees>
                        </ns2:RoomRate>

                    </ns2:RoomRates>
                </ns2:Availability>
            </ns2:Availabilities>
        </ns2:MultiAvailabilityResponse>
    </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>'''

    from pprint import pprint
    pprint(get_details(soap))

Result:

{'roomlist': [{'AmountBeforeTax': u'262.650',
               'RatePlanCode': u'49584IPRTF',
               'RoomTypeCode': u'VW2Q',
               'RoomTypeName': u'PREMIUM VW 2 QEN'},
              {'AmountBeforeTax': u'300.900',
               'RatePlanCode': u'49584IPRTF',
               'RoomTypeCode': u'CLBD',
               'RoomTypeName': u'REG CLUB 2 DOUBLE BEDS'},
              {'AmountBeforeTax': u'449.650',
               'RatePlanCode': u'49584IPRTF',
               'RoomTypeCode': u'JRSQ',
               'RoomTypeName': u'JR SUITE 2 QUEEN BEDS'}]}
Community
  • 1
  • 1
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • I can't confirm it right now, but I suppose you'd add a line like `'Tax': decimal.Decimal(rate['@AmountAfterTax']) - decimal.Decimal(rate['@AmountBeforeTax'])`. – Robᵩ Apr 29 '16 at 15:03
  • Spent time to understand your code. Now, I've got it :) – Raman Balyan Apr 30 '16 at 18:25