欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

使用Python下的XSLT API進行web開發的簡單教程

系統 1982 0

Kafka 樣式的 soap 端點

Christopher Dix 所開發的“Kafka ― XSL SOAP 工具箱”(請參閱 參考資料)是一種用于構造 SOAP 端點的 XSLT 框架。它只涵蓋了 SOAP 1.1,但 Kafka 端點演示了傳遞 UserLand SOAP 驗證器(UserLand SOAP Validator)的能力,并且根據 SOAP 1.2 對它進行更新似乎并不太困難。 清單 1展示了一個樣本 Kafka 端點:求兩數之和的 SOAP 服務器(一個典型而簡單的 SOAP 樣本)。

清單 1. 求兩數之和的 Kafka SOAP 端點

            
                                          
              
                            
                Add
              
              
                http://www.topxml.com/
              
                                          
                
                
                                    
                  
                                    
                    
                    
                    
                  
                
              
            
          

XSLT 端點導入 SOAP 框架(文件 kafka/soap.xsl),然后設置該框架將要使用的參數,并設置它在處理構成 SOAP 消息的整個 XML 文檔的過程中將要分派的模板。全局變量 Method 和 MethodNS 聲明了組成消息的 XML 元素。在處理完 SOAP 信封之后,該框架調用 ProcessPayload 模板,該模板傳入了 XML 主體的有效負載。 xsl:for-each 是將上下文切換成想要的節點的標準技巧。參數 A 和 B 是使用簡單 XPaths 從這個元素讀取的,而框架被再次調用以幫助寫出響應參數。 WriteParameter 模板讓您指定元素名稱、數據類型和每個輸出參數的值。本示例中的響應值是將兩個輸入參數相加所得的結果。

將這個端點部署為服務器相當于設置一個 HTTP 偵聽器。Python 的 BaseHTTPServer 模塊向您提供了所需的機制,能夠輕而易舉地處理該協議的 HTTP 部分。請參閱 清單 2。

清單 2. 用于清單 1 中所實現的 Kafka SOAP 端點的 Python HTTP 框架

            
#HTTP Listener code for SOAP server
import BaseHTTPServer
#The processor class is the core of the XSLT API
from Ft.Xml.Xslt import Processor
#4XSLT uses an InputSource system for reading XML
from Ft.Xml import InputSource
SOAP_IMPL_FILE = "add.xsl"
class KafkaSoapHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  def init(cls):
    from Ft.Lib import Uri
    #Set up a processor instance to use
    KafkaSoapHandler.processor = Processor.Processor()
    #Load it with add.xsl
    add_uri = Uri.OsPathToUri(SOAP_IMPL_FILE, attemptAbsolute=1)
    transform = InputSource.DefaultFactory.fromUri(add_uri)
    KafkaSoapHandler.processor.appendStylesheet(transform)
    #Now the processor is prepped with a transform and can be used
    #over and over for the same transform
    return
  #Make init() a static method of the class
  init = classmethod(init)
  def do_POST(self):
    clen = self.headers.getheader('content-length')
    if clen:
      clen = int(clen)
    else:
      print 'POST ERROR: missing content-length'
      return
    if self.path != '/add':
      self.send_error(404)
    input_body = self.rfile.read(clen)
    #input_body is the request SOAP envelope and contents
    response_body = self._run_through_kafka(input_body)
    #response_body is the response SOAP envelope and contents
    self._send_response(200, 'OK', response_body)
    return
  def _run_through_kafka(self, body):
    #In 4Suite all InputSources have base URIs in case they refer to
    #other URIs in some way and resolution is required.
    #The SOAP messages will not have any such URI references,
    #So use a dummy base URI
    source = InputSource.DefaultFactory.fromString(body, "urn:dummy")
    response = self.processor.run(source)
    return response
  def _send_response(self, code, msg, body):
    #Prepare a normal response
    self.send_response(200, 'OK')
    #Send standard HTP headers
    self.send_header('Content-type','text/html; charset=utf-8')
    self.send_header("Connection", "close")
    self.send_header("Accept-Ranges", "bytes")
    self.send_header('Content-length', len(body)-1)
    self.end_headers()
    #Send the response prepared by the SOAP end point
    self.wfile.write(body)
    return
 
listen_on_port = 8888
#Set up to run on local machine
server_address = ('127.0.0.1', listen_on_port)
KafkaSoapHandler.init()
httpd = BaseHTTPServer.HTTPServer(server_address, KafkaSoapHandler)
print "Listening on port", listen_on_port
#Go into a the main event loop
httpd.serve_forever()


          

我們詳細地注釋了該清單,因此它應該是易于理解的。請注意,這段代碼非常簡單,這是因為它僅需處理該協議的 HTTP 部分,而將 XML 和 SOAP 部分的工作交由 Kafka 框架完成。該服務器專用于一個端點,因此它只須對 XSLT 轉換進行一次解析和設置,然后它就可以簡單地反復為每次新的請求運行該轉換。這就是將處理器設置遷移到特殊的類方法中的原因,處理程序一注冊到服務器就立即調用該方法。 classmethod 內置方法是 Python 2.2 中的新功能,實際上該版本是本例和后面的示例所必需的版本。它提供了隱式類對象 (cls) ,您可以將靜態數據(如已準備好的處理器實例)附加到該對象上,然后通常可以通過普通方法上的 self 實例引用來使用該數據。

我們使用 SOAPpy 0.10.1 的最新發行版(請參閱 參考資料)測試了該端點,該發行版具有許多很棒的新功能,稍后我們將在本專欄中進行討論。 清單 3是使用該端點的 SOAPpy 客戶機。打開一個命令 shell 并為服務器運行 python listing2.py。然后打開另一個 shell 并運行 python listing3.py,該命令將報告正確的響應,形如 Add result: 7.0。

清單 3: 用于求兩數之和的 SOAPpy 客戶機

            
import SOAPpy
ENDPOINT = "http://localhost:8888/add"
ADD_NS = "http://www.topxml.com/"
 
remote = SOAPpy.SOAPProxy(ENDPOINT, namespace=ADD_NS)
print "Add result:", remote.Add(A=3, B=4)


          

使用描述

正如我們先前所說的,不僅 XML 中的有效負載是有用的 Web 服務特性,描述也是有用的特性。 清單 4是一個用于添加服務的 WSDL 文件,它是根據 Christopher Dix 的原始文件修改而得到的。它是 WSDL 1.1 版本的。

清單 4. 用于添加服務的 WSDL

            
              
                
                
              
              
                
              
              
                
                  
                  
                
              
              
                
                
                  
                  
                  
                  
                    
                  
                
              
              
                
                  
                
              
            
          

清單 5提供了一個為端點用戶呈現有用信息的 XSLT 腳本。它是從先前的 developerWorks 文章“WSDL processing with XSLT”(請參閱 參考資料)中所開發的一個轉換改編而來的。它使用了許多自由方式(liberty)和快捷方式(尤其是在它處理 WSDL 上下文中的限定名時),但它也許可用于目前使用的大多數 WSDL 1.1 文件。

清單 5. XSLT 腳本

            
              
                            
              
              
              
              
                
                  
Service summary: <xsl:value-of select='wsdl:definitions/@name'/>
   
                
                
                

Service summary:

Service " " hosted at

Operation " " message details:

通常在 Web 服務本身所在的主機上提供該服務人性化的 WSDL 描述是很方便的。 清單 6是 清單 2的變體,它也完成這一任務。它實際上提供三種功能:

  1. ??? 對于端口 9000 上的 GET 請求:提供該 Web 服務調用消息的易于理解的描述
  2. ??? 對于端口 8888 上的 GET 請求:提供未經處理的 WSDL 文件
  3. ??? 對于端口 8888 上的 POST 請求:執行 SOAP 請求。

清單 6. 清單 2 的變體

            
#HTTP Listener code for SOAP server
import BaseHTTPServer
#The processor class is the core of the XSLT API
from Ft.Xml.Xslt import Processor
#4XSLT uses an InputSource system for reading XML
from Ft.Xml import InputSource
SOAP_IMPL_FILE = "add.xsl"
WSDL_FILE = "listing4.xml"
HTML_VIEW_TRANSFORM = "listing5.xslt"
class KafkaSoapHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  def init(cls):
    from Ft.Lib import Uri
    #Set up a processor instance to use
    cls.processor = Processor.Processor()
    #Load it with add.xsl
    add_uri = Uri.OsPathToUri(SOAP_IMPL_FILE, attemptAbsolute=1)
    transform = InputSource.DefaultFactory.fromUri(add_uri)
    cls.processor.appendStylesheet(transform)
    #Now the processor is prepped with a transform and can be used
    #over and over for the same transform
    #Prep for WSDL requests
    cls.wsdl = open(WSDL_FILE).read()
    return
  #Make init() a static method of the class
  init = classmethod(init)
  def do_POST(self):
    clen = self.headers.getheader('content-length')
    if clen:
      clen = int(clen)
    else:
      print 'POST ERROR: missing content-length'
      return
    if self.path != '/add':
      self.send_error(404)
    input_body = self.rfile.read(clen)
    #input_body is the request SOAP envelope and contents
    response_body = self._run_through_kafka(input_body)
    #response_body is the response SOAP envelope and contents
    _send_response(self, 200, 'OK', response_body)
    return
  def do_GET(self):
    #response_body is the WSDL file
    _send_response(self, 200, 'OK', self.wsdl)
    return
  
  def _run_through_kafka(self, body):
    #In 4Suite all InputSources have base URIs in case they refer to
    #other URIs in some way and resolution is required.
    #The SOAP messages will not have any such URI references,
    #So use a dummy base URI
    source = InputSource.DefaultFactory.fromString(body, "urn:dummy")
    response = self.processor.run(source)
    return response
class HtmlHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  def init(cls):
    from Ft.Lib import Uri
    #Perform the transform once and store the result
    processor = Processor.Processor()
    html_desc_uri = Uri.OsPathToUri(HTML_VIEW_TRANSFORM,
                    attemptAbsolute=1)
    transform = InputSource.DefaultFactory.fromUri(html_desc_uri)
    processor.appendStylesheet(transform)
    wsdl_uri = Uri.OsPathToUri(WSDL_FILE, attemptAbsolute=1)
    source = InputSource.DefaultFactory.fromUri(wsdl_uri)
    cls.html_desc = processor.run(source)
    return
  #Make init() a static class method
  init = classmethod(init)
  def do_GET(self):
    #response_body is the WSDL file
    _send_response(self, 200, 'OK', self.html_desc)
    return
#Turn _send_response into a global function
#for sharing between the classes
def _send_response(handler, code, msg, body):
    #Prepare a normal response
    handler.send_response(200, 'OK')
    #Send standard HTP headers
    handler.send_header('Content-type', 'text/html; charset=utf-8')
    handler.send_header("Connection", "close")
    handler.send_header("Accept-Ranges", "bytes")
    handler.send_header('Content-length', len(body)-1)
    handler.end_headers()
    #Send the response prepared by the SOAP end point
    handler.wfile.write(body)
    return
 
def soap_listener_function():
  listen_on_port = 8888
  #Set up to run on local machine
  server_address = ('127.0.0.1', listen_on_port)
  KafkaSoapHandler.init()
  httpd = BaseHTTPServer.HTTPServer(server_address, KafkaSoapHandler)
  print "Listening for GET and POST on port", listen_on_port
  #Go into a the main event loop
  httpd.serve_forever()
def html_listener_function():
  listen_on_port = 9000
  #Set up to run on local machine
  server_address = ('127.0.0.1', listen_on_port)
  HtmlHandler.init()
  httpd = BaseHTTPServer.HTTPServer(server_address, HtmlHandler)
  print "Listening for GET on port", listen_on_port
  #Go into a the main event loop
  httpd.serve_forever()
  return
import time
from threading import Thread
soap_thread = Thread(None, soap_listener_function)
html_thread = Thread(None, html_listener_function)
soap_thread.start()
#Pause before spawning the next thread
time.sleep(1)
html_thread.start()


          

通過在服務器上定義 do_GET 和 do_POST ,您可以在單個服務器實例上處理 GET 和 POST 請求,但是因為所使用的簡單事件循環的性質,您可以使用線程技術在不同端口上進行偵聽。這讓您同時運行兩個服務器實例。線程技術是方法之一,而使用異步事件處理程序是另一種方法。Python 2.2 為更輕松地支持后一種技術而引入了 asyncore 模塊,我們在本專欄的上一篇文章中介紹了這種方法(請參閱 參考資料)。這一次我們將舉例說明線程技術的用法。關于使用線程技術還是使用異步技術的問題,Python 2.2 文檔提出了很好的建議。

僅當您的程序很大程度上受 I/O 限制時,[異步方法才是] 真正實用的。如果您的程序受處理器限制,那么搶先式調度的線程可能是您所真正需要的。但是,網絡服務器很少受處理器限制。

圖 1顯示了易于理解的 Web 服務描述的瀏覽器視圖。

使用Python下的XSLT API進行web開發的簡單教程_第1張圖片

結束語

請將這一切都看作實驗素材。Kafka 已經相當落伍了 ― 它似乎從 2001 年以來就沒有得到過維護,并且它使用了相當差勁的 XSLT 樣式(其作者坦率地承認自己是個 XSLT 菜鳥)。但其思想是非常有用的,并且很有價值。只需要作很小的努力就可以將它更新到 SOAP 1.2 并擴展其能力。我們所提供的 WSDL 表示轉換也只是一個起點。也可以將它更新到 WSDL 1.2 并可擴展它以顯示關于 Web 服務的更多信息。還應該更新它以利用名稱空間軸和其它 XSLT 功能以便進行更為正確的處理。

XSLT 是一個沙箱,使用各種語言和環境的開發人員都可以在其中施展身手。Kafka 是由一位堅定的 .NET 開發人員開發的,但我們也可以很快地學會它和利用它。這就是擁有一種既可以處理 XML 也可處理 Web 服務的通用語言(lingua franca)的威力。我們預計可以使用用于 Web 服務的 XSLT 模塊的領域將繼續擴展。如果是這樣,本文所提供的基本技術可能會促使 Python 程序員們馬上使用這些有用的技術。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精品久久一区二区三区 | 一区二区三区在线 | 日本 | 蜜桃视频在线观看免费视频网站www | 99在线精品视频在线观看 | 国产精品蜜芽在线观看 | 亚洲精品一区二区三区在线观看 | www.伊人| 国产1区在线 | 国产精品久久久久影院色老大 | 九九精品视频一区在线 | 国产精品专区第1页 | 精品网站999 | 日韩特级毛片 | 伊人二本二区 | 亚州a | 免费看国产片在线观看 | 国产不卡视频在线播放 | 老司机午夜免费精品视频 | 欧美三级成版人版在线观看 | 久久一本日韩精品中文字幕屁孩 | wankzhd| 欧美在线观看a | 国产精品无码专区在线观看 | 波多野结衣全集在线观看 | 夜夜爽夜夜叫夜夜高潮漏水 | 久久中文字幕网 | 香港一级毛片免费看 | 亚洲成av| 波多野结衣免费线在线 | 色综合久久天天综合网 | 久久特级毛片 | 99久热国产精品视频尤物不卡 | 五月婷婷爱 | 小视频网址 | 欧美日韩北条麻妃一区二区 | 国产精品国产精品 | 日韩国产一区二区 | 久草综合在线视频 | 草逼com| 亚洲色图欧美色 | 日本黄页网站免费 |