Python 从SOAP xml响应获取所需的详细信息

Python 从SOAP xml响应获取所需的详细信息,python,xml,dictionary,soap,Python,Xml,Dictionary,Soap,我得到的SOAP xml响应如下: <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="Successfu

我得到的SOAP xml响应如下:

<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>

在两张女王标志性凯悦大床中的一张上舒适地休息,床上配有精致的亚麻布、羽绒毯和丰满的枕头。
一张特大双人床或两张双人床,配有豪华床单、羽绒毯和毛绒枕头
在我们精致的芝加哥市中心客房内放松身心,享受城市、河流和湖景

我正在使用xmltodict库解析它。现在,我只想在我的应用程序中使用此响应中的一些元素。我想要的元素是:RatePlanCode、RoomTypeCode、RoomTypeName、税前金额。 另外,我希望根据AmountBeforeTax对响应进行排序,并以字典的形式获得结果,my_dict={'roomlist':[{'RoomTypeCode':value,'RatePlanCode':vlaue,'RoomTypeName':value,'AmountBeforeTax':value}]}


从早上开始,我就没有使用SOAP-xml,我的头也没撞过。任何帮助都将不胜感激。谢谢

我不认为
xmltodict
是最好的选择。也许这是一个更好的选择

话虽如此,这里有一个基于
xmltodict
的程序,它解析您上面给出的SOAP示例

# 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))

XML中的标记不匹配。结尾应该有一个
吗?@Robᵩ 是的……我错过了……你能帮我找到解决方案吗?就像我在回答中说的,我认为
xmltodict
不是一个很好的选择。@Robᵩ 我问了一个类似的问题,但有点小题大做。你也能帮我一下吗..我现在不能确认,但我想你应该添加一行类似于
'Tax':decimal.decimal(rate['@AmountAfterTax'])-decimal.decimal(rate['@AmountBeforeTax'])
。花时间理解你的代码。现在,我明白了:)
{'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'}]}