从soapxml响应获取详细信息

2024-09-27 04:28:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用xmltodict库解析下面的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="GBP" HotelCode="HY-LONGE">
                <ns2:GuestCount AdultCount="1" ChildCount="0"/>
                <ns2:RoomTypes>
                    <ns2:RoomType RoomTypeCode="KING" RoomTypeName="Andaz King">
                        <ns2:RoomTypeDescription>A 29-square-metre room ,Modern furnishings include oversized work desk, plus bathroom with fast-fill tub and heated towel rail.</ns2:RoomTypeDescription>
                    </ns2:RoomType>
                    <ns2:RoomType RoomTypeCode="TWIN" RoomTypeName="Andaz Twin">
                        <ns2:RoomTypeDescription>A 29-square-metre room ,Modern furnishings include oversized work desk, plus bathroom with fast-fill tub and heated towel rail.</ns2:RoomTypeDescription>
                    </ns2:RoomType>
                    <ns2:RoomType RoomTypeCode="QUEN" RoomTypeName="Andaz Queen">
                        <ns2:RoomTypeDescription>A 26-square-metre room ,Modern furnishings include oversized work desk, plus bathroom with fast-fill tub and heated towel rail.</ns2:RoomTypeDescription>
                    </ns2:RoomType>
                </ns2:RoomTypes>
                <ns2:RatePlans>
                    <ns2:RatePlan RatePlanCode="49584WADPF2" RatePlanName="Advance Purchase">
                        <ns2:RatePlanDescription>Advance Purchase</ns2:RatePlanDescription>
                    </ns2:RatePlan>
                    <ns2:RatePlan RatePlanCode="49584WADPF" RatePlanName="Advance Purchase">
                        <ns2:RatePlanDescription>Advance Purchase</ns2:RatePlanDescription>
                    </ns2:RatePlan>
                    <ns2:RatePlan RatePlanCode="49584IPRTF" RatePlanName="Partner Rate">
                        <ns2:RatePlanDescription>Partner Rate</ns2:RatePlanDescription>
                    </ns2:RatePlan>
                </ns2:RatePlans>
                <ns2:RoomRates>
                    <ns2:RoomRate RatePlanCode="49584WADPF2" RoomTypeCode="KING">
                        <ns2:Rates>
                            <ns2:Rate AmountAfterTax="249.900" AmountBeforeTax="249.900" EffectiveDate="2016-05-05" ExpireDate="2016-05-06"/>
                        </ns2:Rates>
                        <ns2:Fees>
                            <ns2:Fee Amount="0.000" ChargeType="Tax" Type="Exclusive" Unit="PER_ROOM_PER_NIGHT"/>
                        </ns2:Fees>
                    </ns2:RoomRate>
                    <ns2:RoomRate RatePlanCode="49584WADPF2" RoomTypeCode="TWIN">
                        <ns2:Rates>
                            <ns2:Rate AmountAfterTax="249.900" AmountBeforeTax="249.900" EffectiveDate="2016-05-05" ExpireDate="2016-05-06"/>
                        </ns2:Rates>
                        <ns2:Fees>
                            <ns2:Fee Amount="0.000" ChargeType="Tax" Type="Exclusive" Unit="PER_ROOM_PER_NIGHT"/>
                        </ns2:Fees>
                    </ns2:RoomRate>
                    <ns2:RoomRate RatePlanCode="49584WADPF" RoomTypeCode="QUEN">
                        <ns2:Rates>
                            <ns2:Rate AmountAfterTax="249.900" AmountBeforeTax="249.900" EffectiveDate="2016-05-05" ExpireDate="2016-05-06"/>
                        </ns2:Rates>
                        <ns2:Fees>
                            <ns2:Fee Amount="0.000" ChargeType="Tax" Type="Exclusive" Unit="PER_ROOM_PER_NIGHT"/>
                        </ns2:Fees>
                    </ns2:RoomRate>
                </ns2:RoomRates>
            </ns2:Availability>
            <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:RoomTypes>
                <ns2:RatePlans>
                    <ns2:RatePlan RatePlanCode="49584IPRTF" RatePlanName="Partner Rate">
                        <ns2:RatePlanDescription>Partner Rate</ns2:RatePlanDescription>
                        <ns2:CancelPolicy NonRefundable="true">
                            <ns2:CancelPenalties/>
                        </ns2:CancelPolicy>
                    </ns2:RatePlan>
                    <ns2:RatePlan RatePlanCode="49584WPAWAF" RatePlanName="Bed and Breakfast">
                        <ns2:RatePlanDescription>Bed and Breakfast</ns2:RatePlanDescription>
                        <ns2:CancelPolicy NonRefundable="true">
                            <ns2:CancelPenalties/>
                        </ns2:CancelPolicy>
                    </ns2:RatePlan>
                </ns2:RatePlans>
                <ns2:RoomRates>
                    <ns2:RoomRate RatePlanCode="49584IPRTF" RoomTypeCode="JRSQ">
                        <ns2:Rates>
                            <ns2:Rate AmountAfterTax="543.134" AmountBeforeTax="466.650" EffectiveDate="2016-05-05" ExpireDate="2016-05-06"/>
                        </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="370.004" AmountBeforeTax="317.900" EffectiveDate="2016-05-05" ExpireDate="2016-05-06"/>
                        </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="325.485" AmountBeforeTax="279.650" EffectiveDate="2016-05-05" ExpireDate="2016-05-06"/>
                        </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响应获取所需详细信息的代码:

^{pr2}$

我能够从SOAP消息中获得所需的详细信息,并将其转换为Dictionary的所需格式。但是,从上面共享的这个特定的SOAP消息获取详细信息时遇到了问题。在所有其他情况下,我只得到单个酒店的响应,其中包含不同数量的组合,但是在这个SOAP响应中,我有两个酒店,我的解析代码同时从两个酒店获取房间的价格并对其进行排序。但是,我想对第一个酒店选项进行排序,然后对第二个酒店选项进行排序。酒店的数量可能会有所不同,所以尽量提供通用的解决方案,而不管酒店的数量。在

任何帮助都是值得的。谢谢!在


Tags: andrate酒店soapratesfeesns2roomtype
2条回答

考虑使用XSLT简化XML,这是一种专门用于转换XML文档的声明性编程语言。Python可以使用lxml模块运行xslt1.0。从那里将转换后的树解析为一个带有xmltodict的字典,该字典可以进一步解析为json。所有三个输出包括以下内容:

XSLT脚本(另存为.xsl文件,在下面的.py脚本中引用)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
               xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:ns2="http://www.derbysoft.com/doorway">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <!  Response Level  >
  <xsl:template match="ns2:MultiAvailabilityResponse">
    <Responses>      
      <xsl:apply-templates select="ns2:Availabilities"/>
    </Responses>
  </xsl:template>

  <xsl:template match="ns2:Availabilities">
    <xsl:apply-templates select="ns2:Availability">
      <xsl:sort select="@CurrencyCode" order="descending"/>
    </xsl:apply-templates>      
  </xsl:template>

  <!  Hotel Level  >
  <xsl:template match="ns2:Availability">    
    <Hotel>      
      <xsl:apply-templates select="ns2:RoomRates"/>
    </Hotel>
  </xsl:template>

  <!  Room Rates Level  >
  <xsl:template match="ns2:RoomRates">        
    <xsl:apply-templates select="ns2:RoomRate">          
      <xsl:sort select="descendant::ns2:Rate/@AmountBeforeTax"
                order="ascending" data-type="number"/>
    </xsl:apply-templates>    
  </xsl:template>

  <!  Room Rate Level  >
  <xsl:template match="ns2:RoomRate">
    <RoomRate>      
      <ibp>dbs</ibp>
      <rL><xsl:apply-templates select="ns2:Rates"/></rL>
      <hc><xsl:value-of select="ancestor::ns2:Availability/@HotelCode"/></hc>
      <hn></hn>
    </RoomRate>
  </xsl:template>  

  <!  Rates Level  >
  <xsl:template match="ns2:Rates/*">    
    <xsl:variable name="rtc" select="ancestor::ns2:RoomRate/@RoomTypeCode"/>
    <rtc><xsl:value-of select="$rtc"/></rtc>
    <rpc><xsl:value-of select="ancestor::ns2:RoomRate/@RatePlanCode"/></rpc>
    <rtn><xsl:value-of select="ancestor::ns2:Availability/ns2:RoomTypes/
                               ns2:RoomType[@RoomTypeCode=$rtc]/@RoomTypeName"/></rtn>
    <rmt><xsl:value-of select="@AmountBeforeTax"/></rmt>
    <cur><xsl:value-of select="ancestor::ns2:Availability/@CurrencyCode"/></cur>
    <ttc><xsl:value-of select="@AmountAfterTax - @AmountBeforeTax"/></ttc>
    <egc>0</egc>
    <long></long>
  </xsl:template>

</xsl:transform>

PythonScript(输出到xml、dict和json类型)

^{pr2}$

转换的XML输出

<?xml version='1.0' encoding='UTF-8'?>
<Responses xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://www.derbysoft.com/doorway">
  <Hotel>
    <RoomRate>
      <ibp>dbs</ibp>
      <rL>
        <rtc>VW2Q</rtc>
        <rpc>49584IPRTF</rpc>
        <rtn/>
        <rmt>279.650</rmt>
        <cur>USD</cur>
        <ttc>45.835</ttc>
        <egc>0</egc>
        <long/>
      </rL>
      <hc>HY-CHIRC</hc>
      <hn/>
    </RoomRate>
    <RoomRate>
      <ibp>dbs</ibp>
      <rL>
        <rtc>CLBD</rtc>
        <rpc>49584IPRTF</rpc>
        <rtn>REG CLUB 2 DOUBLE BEDS</rtn>
        <rmt>317.900</rmt>
        <cur>USD</cur>
        <ttc>52.104</ttc>
        <egc>0</egc>
        <long/>
      </rL>
      <hc>HY-CHIRC</hc>
      <hn/>
    </RoomRate>
    <RoomRate>
      <ibp>dbs</ibp>
      <rL>
        <rtc>JRSQ</rtc>
        <rpc>49584IPRTF</rpc>
        <rtn>JR SUITE 2 QUEEN BEDS</rtn>
        <rmt>466.650</rmt>
        <cur>USD</cur>
        <ttc>76.484</ttc>
        <egc>0</egc>
        <long/>
      </rL>
      <hc>HY-CHIRC</hc>
      <hn/>
    </RoomRate>
  </Hotel>
  <Hotel>
    <RoomRate>
      <ibp>dbs</ibp>
      <rL>
        <rtc>KING</rtc>
        <rpc>49584WADPF2</rpc>
        <rtn>Andaz King</rtn>
        <rmt>249.900</rmt>
        <cur>GBP</cur>
        <ttc>0</ttc>
        <egc>0</egc>
        <long/>
      </rL>
      <hc>HY-LONGE</hc>
      <hn/>
    </RoomRate>
    <RoomRate>
      <ibp>dbs</ibp>
      <rL>
        <rtc>TWIN</rtc>
        <rpc>49584WADPF2</rpc>
        <rtn>Andaz Twin</rtn>
        <rmt>249.900</rmt>
        <cur>GBP</cur>
        <ttc>0</ttc>
        <egc>0</egc>
        <long/>
      </rL>
      <hc>HY-LONGE</hc>
      <hn/>
    </RoomRate>
    <RoomRate>
      <ibp>dbs</ibp>
      <rL>
        <rtc>QUEEN</rtc>
        <rpc>49584WADPF</rpc>
        <rtn>Andaz Queen</rtn>
        <rmt>249.900</rmt>
        <cur>GBP</cur>
        <ttc>0</ttc>
        <egc>0</egc>
        <long/>
      </rL>
      <hc>HY-LONGE</hc>
      <hn/>
    </RoomRate>
  </Hotel>
</Responses>

Python字典

OrderedDict([('Responses', OrderedDict([('@xmlns:SOAP-ENV', 'http://schemas.xmlsoap.org/soap/envelope/'), 
('@xmlns:ns2', 'http://www.derbysoft.com/doorway'), ('Hotel', [OrderedDict([('RoomRate', [OrderedDict([('ibp', 'dbs'), 
('rL', OrderedDict([('rtc', 'VW2Q'), ('rpc', '49584IPRTF'), ('rtn', None), ('rmt', '279.650'), ('cur', 'USD'), 
('ttc', '45.835'), ('egc', '0'), ('long', None)])), ('hc', 'HY-CHIRC'), ('hn', None)]), OrderedDict([('ibp', 'dbs'), 
('rL', OrderedDict([('rtc', 'CLBD'), ('rpc', '49584IPRTF'), ('rtn', 'REG CLUB 2 DOUBLE BEDS'), ('rmt', '317.900'), 
('cur', 'USD'), ('ttc', '52.104'), ('egc', '0'), ('long', None)])), ('hc', 'HY-CHIRC'), ('hn', None)]), 
OrderedDict([('ibp', 'dbs'), ('rL', OrderedDict([('rtc', 'JRSQ'), ('rpc', '49584IPRTF'), ('rtn', 'JR SUITE 2 QUEEN BEDS'), 
('rmt', '466.650'), ('cur', 'USD'), ('ttc', '76.484'), ('egc', '0'), ('long', None)])), ('hc', 'HY-CHIRC'), 
('hn', None)])])]), OrderedDict([('RoomRate', [OrderedDict([('ibp', 'dbs'), ('rL', OrderedDict([('rtc', 'KING'), 
('rpc', '49584WADPF2'), ('rtn', 'Andaz King'), ('rmt', '249.900'), ('cur', 'GBP'), ('ttc', '0'), ('egc', '0'), 
('long', None)])), ('hc', 'HY-LONGE'), ('hn', None)]), OrderedDict([('ibp', 'dbs'), ('rL', OrderedDict([('rtc', 'TWIN'), 
('rpc', '49584WADPF2'), ('rtn', 'Andaz Twin'), ('rmt', '249.900'), ('cur', 'GBP'), ('ttc', '0'), ('egc', '0'), 
('long', None)])), ('hc', 'HY-LONGE'), ('hn', None)]), OrderedDict([('ibp', 'dbs'), ('rL', OrderedDict([('rtc', 'QUEEN'), 
('rpc', '49584WADPF'), ('rtn', 'Andaz Queen'), ('rmt', '249.900'), ('cur', 'GBP'), ('ttc', '0'), ('egc', '0'), 
('long', None)])), ('hc', 'HY-LONGE'), ('hn', None)])])])])]))])

JSON输出

{
     "Responses": {
          "@xmlns:SOAP-ENV": "http://schemas.xmlsoap.org/soap/envelope/",
          "@xmlns:ns2": "http://www.derbysoft.com/doorway",
          "Hotel": [
               {
                    "RoomRate": [
                         {
                              "ibp": "dbs",
                              "rL": {
                                   "rtc": "VW2Q",
                                   "rpc": "49584IPRTF",
                                   "rtn": null,
                                   "rmt": "279.650",
                                   "cur": "USD",
                                   "ttc": "45.835",
                                   "egc": "0",
                                   "long": null
                              },
                              "hc": "HY-CHIRC",
                              "hn": null
                         },
                         {
                              "ibp": "dbs",
                              "rL": {
                                   "rtc": "CLBD",
                                   "rpc": "49584IPRTF",
                                   "rtn": "REG CLUB 2 DOUBLE BEDS",
                                   "rmt": "317.900",
                                   "cur": "USD",
                                   "ttc": "52.104",
                                   "egc": "0",
                                   "long": null
                              },
                              "hc": "HY-CHIRC",
                              "hn": null
                         },
                         {
                              "ibp": "dbs",
                              "rL": {
                                   "rtc": "JRSQ",
                                   "rpc": "49584IPRTF",
                                   "rtn": "JR SUITE 2 QUEEN BEDS",
                                   "rmt": "466.650",
                                   "cur": "USD",
                                   "ttc": "76.484",
                                   "egc": "0",
                                   "long": null
                              },
                              "hc": "HY-CHIRC",
                              "hn": null
                         }
                    ]
               },
               {
                    "RoomRate": [
                         {
                              "ibp": "dbs",
                              "rL": {
                                   "rtc": "KING",
                                   "rpc": "49584WADPF2",
                                   "rtn": "Andaz King",
                                   "rmt": "249.900",
                                   "cur": "GBP",
                                   "ttc": "0",
                                   "egc": "0",
                                   "long": null
                              },
                              "hc": "HY-LONGE",
                              "hn": null
                         },
                         {
                              "ibp": "dbs",
                              "rL": {
                                   "rtc": "TWIN",
                                   "rpc": "49584WADPF2",
                                   "rtn": "Andaz Twin",
                                   "rmt": "249.900",
                                   "cur": "GBP",
                                   "ttc": "0",
                                   "egc": "0",
                                   "long": null
                              },
                              "hc": "HY-LONGE",
                              "hn": null
                         },
                         {
                              "ibp": "dbs",
                              "rL": {
                                   "rtc": "QUEEN",
                                   "rpc": "49584WADPF",
                                   "rtn": "Andaz Queen",
                                   "rmt": "249.900",
                                   "cur": "GBP",
                                   "ttc": "0",
                                   "egc": "0",
                                   "long": null
                              },
                              "hc": "HY-LONGE",
                              "hn": null
                         }
                    ]
               }
          ]
     }
}

您正在从所有房价结果(尽管是所有酒店)创建列表理解,但酒店代码不在任何类型的循环之外,与列表处于同一级别。 所以,你总是只能得到最后一家酒店。在

代码:

 'hc': _availability['@HotelCode'],

变量\u availability是前一个循环“for-u-availability-in-availability”中的最后一次出现。这不是正常的循环。在

在我看来,这样复杂的数据结构很难阅读和使用,也许你应该考虑用面向对象的方法来处理对象属性中的数据。在

如果您坚持使用此类数据结构,可以这样做:

^{pr2}$

相关问题 更多 >

    热门问题