2014-02-05 64 views
0

I am a complete Python noob 現在已經完成了鋪墊,我試圖從SOAP響應中解析出一些信息。 的效應初探的主體是下面:爲什麼我沒有得到正確的答覆?

<soap:Body> 
    <ProcessMessageResponse xmlns="http://www.starstandards.org/webservices/2005/10/transport"> 
    <payload> 
     <content id="Content0"> 
      <CustomerLookupResponse xmlns=""> 
       <Customer> 
       <CompanyNumber>ZQ1</CompanyNumber> 
       <CustomerNumber>1051012</CustomerNumber> 
       <TypeCode>I</TypeCode> 
       <LastName>NAME</LastName> 
       <FirstName>BASIC</FirstName> 
       <MiddleName/> 
       <Salutation/> 
       <Gender/> 
       <Language/> 
       <Address1/> 
       <Address2/> 
       <Address3/> 
       <City/> 
       <County/> 
       <StateCode/> 
       <ZipCode>0</ZipCode> 
       <PhoneNumber>0</PhoneNumber> 
       <BusinessPhone>0</BusinessPhone> 
       <BusinessExt>0</BusinessExt> 
       <FaxNumber>0</FaxNumber> 
       <BirthDate>0</BirthDate> 
       <DriversLicense/> 
       <Contact/> 
       <PreferredContact/> 
       <MailCode/> 
       <TaxExmptNumber/> 
       <AssignedSalesperson/> 
       <CustomerType/> 
       <PreferredPhone/> 
       <CellPhone>0</CellPhone> 
       <PagePhone>0</PagePhone> 
       <OtherPhone>0</OtherPhone> 
       <OtherPhoneDesc/> 
       <Email1/> 
       <Email2/> 
       <OptionalField/> 
       <AllowContactByPostal/> 
       <AllowContactByPhone/> 
       <AllowContactByEmail/> 
       <BusinessPhoneExtension/> 
       <InternationalBusinessPhone/> 
       <InternationalCellPhone/> 
       <ExternalCrossReferenceKey>0</ExternalCrossReferenceKey> 
       <InternationalFaxNumber/> 
       <InternationalOtherPhone/> 
       <InternationalHomePhone/> 
       <CustomerPreferredName/> 
       <InternationalPagerPhone/> 
       <PreferredLanguage/> 
       <LastChangeDate>20130401</LastChangeDate> 
       <Vehicles/> 
       <CCID/> 
       <CCCD>0</CCCD> 
       </Customer> 
      </CustomerLookupResponse> 
     </content> 
    </payload> 
    </ProcessMessageResponse> 
</soap:Body> 

和我有下面的代碼片段顯示什麼我做了解析出我想要的迴應:

customer_number = '' 
customer_first_name = '' 
customer_last_name = '' 

def send_customer_lookup(data): 
    soap_action = 'http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage' 
source_port = random.randint(6000, 20000) 
    webservice = httplib.HTTPSConnection('otqa.arkona.com', source_address=('', source_port)) 
    webservice.putrequest('POST', '/OpenTrack/Webservice.asmx?wsdl') 
    webservice.putheader('User-Agent', 'OpenTrack-Heartbeat') 
    webservice.putheader('Content-Type', 'application/soap+xml') 
    webservice.putheader('Content-Length', '%d' % len(data)) 
    webservice.putheader('SOAPAction', soap_action) 
    webservice.endheaders() 
    webservice.send(data) 
    response = webservice.getresponse() 
    response_xml = str(response.read()) 

    doc = ET.fromstring(response_xml) 
    for customer in doc.findall('.//{http://www.starstandards.org/webservices/2005/10/transport}Payload'): 
     global customer_number 
     global customer_first_name 
     global customer_last_name 
     customer_number = customer.findtext('{http://www.starstandards.org/webservices/2005/10/transport}CustomerNumber') 
     customer_first_name = customer.findtext('{http://www.starstandards.org/webservices/2005/10/transport}FirstName') 
     customer_last_name = customer.findtext('{http://www.starstandards.org/webservices/2005/10/transport}LastName') 

    webservice.close() 
    return customer_number, customer_first_name, customer_last_name, response_xml 

我不能肯定我爲什麼我得到了一個輸出' ', ' ', ' ', <xml response>...

+0

(不是一個答案,但)很多是webservice.putrequest東西升像它這樣的ooks應該被抽象爲一個通用的send_soap_request()函數。 –

+0

@HughBothwell謝謝你,我會考慮這一點,現在我只需要一些有用的東西。 – DarthOpto

回答

1

它看起來像你在過分指定字段名稱,因此它們不匹配任何東西,因此你的for customer in ...永遠不會運行。試試這個:

import httplib 
import xml.etree.ElementTree as ET 

def send_customer_lookup(data): 
    soap_action = 'http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage' 
    source_port = random.randint(6000, 20000) 
    with httplib.HTTPSConnection('otqa.arkona.com', source_address=('', source_port)) as webservice: 
     webservice.putrequest('POST', '/OpenTrack/Webservice.asmx?wsdl') 
     webservice.putheader('User-Agent', 'OpenTrack-Heartbeat') 
     webservice.putheader('Content-Type', 'application/soap+xml') 
     webservice.putheader('Content-Length', '%d' % len(data)) 
     webservice.putheader('SOAPAction', soap_action) 
     webservice.endheaders() 
     webservice.send(data) 
     response_xml = str(webservice.getresponse().read()) 

    doc = ET.fromstring(response_xml) 
    results = [] 
    for customer in doc.findall('.//CustomerLookupResponse/'): 
     customer_number  = customer.findtext('CustomerNumber') 
     customer_first_name = customer.findtext('FirstName') 
     customer_last_name = customer.findtext('LastName') 
     results.append((customer_number, customer_first_name, customer_last_name)) 

    return results 

此外,全局變量名一般都是邪惡的;我認爲你添加了他們,因爲你得到'變量未定義'的錯誤?這應該是一個線索,for循環實際上並沒有運行。

+0

非常感謝。這非常有幫助。 – DarthOpto

0

你可以使用xml.dom.minidom:

from xml.dom import minidom 

def parse_customer_data(response_xml): 
    results = [] 
    dom = minidom.parseString(response_xml) 
    customers=dom.getElementsByTagName('Customer') 
    for c in customers:                              
     results.append({ 
      "cnum" : c.getElementsByTagName('CustomerNumber')[0].firstChild.data, 
      "lname" : c.getElementsByTagName('LastName')[0].firstChild.data, 
      "fname" : c.getElementsByTagName('FirstName')[0].firstChild.data 
     }) 
    return results 

if __name__ == "__main__": 
    response_xml = open("soap.xml").read() 
    results = parse_customer_data(response_xml) 
    print(results) 

注意,輸入文件,soap.xml: 1.我添加XML版本/ SOAP:你周圍所提供的XML元素信封,否則它不會解析 2.我添加了另一個客戶元素來測試我的代碼

輸出:

$ python soap.py 
[{'lname': u'NAME1', 'cnum': u'1051012', 'fname': u'BASIC1'}, {'lname': u'NAME2', 'cnum': u'1051013', 'fname': u'BASIC2'}] 
+0

感謝您的建議。它也起作用。我去了另一個答案,因爲我不必安裝另一個插件。 – DarthOpto

相關問題