15. [IMPOTS] alıştırması ile XML
Daha önce birçok kez incelenen bu alıştırmada, sunucu sonuçları XML akışı biçiminde istemciye geri gönderir:
- Hata durumunda <reponse><erreur>msg</erreur></reponse>;
- Vergi hesaplanabildiyse <reponse><impot>valeur</impot></reponse>.
XML belgesinin analiziyle ilgili az önce öğrendiklerimizi kullanıyoruz.
![]() |
15.1. Web hizmeti
Web hizmeti, müşteriye gönderilen XML yanıtının biraz farklı olması dışında, daha önce incelediğimiz web hizmetinden farklı değildir. Mimari aynı kalır:
![]() |
Web hizmeti (impots_web_02)
#!D:\Programs\ActivePython\Python2.7.2\python.exe
# -*- coding=Utf-8 -*-
# Impots* sınıfları modülünün içe aktarılması
from impots import *
import cgi,cgitb,re
# hata ayıklama bilgilerinin görüntülenmesine izin verilir
cgitb.enable()
# ------------------------------------------------
# vergi web hizmeti
# ------------------------------------------------
# vergi hesaplaması için gerekli veriler mysqL TABLE
# tabloya yerleştirilmiştir. Tablonun yapısı şöyledir
# sınırlar decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
# vergi mükelleflerine ait parametreler (medeni durum, çocuk sayısı, yıllık maaş)
# müşteri tarafından params=medeni durum, çocuk sayısı, yıllık maaş biçiminde gönderilir
# sonuçlar (medeni durum, çocuk sayısı, yıllık maaş, ödenecek vergi) müşteriye geri gönderilir
# <vergi>değer</vergi> biçiminde
# veya parametreler geçersizse <hata>msg</hata> biçiminde
# sunucu, müşteriye biçimlendirilmemiş metin gönderir
print "Content-Type: text/plain\n"
# yanıtın başlangıcı
print "<reponse>"
# sabitlerin tanımlanması
USER="root"
PWD=""
HOTE="localhost"
BASE="dbimpots"
TABLE="impots"
# [metier] katmanının örneklenmesi
try:
metier=ImpotsMetier(ImpotsMySQL(HOTE,USER,PWD,BASE,TABLE))
except (IOError, ImpotsError) as infos:
print ("<erreur>Une erreur s'est produite : {0}</erreur>".format(infos))
sys.exit()
# istemci tarafından sunucuya gönderilen satırı alıyoruz
params=cgi.FieldStorage().getlist('params')
# parametre yoksa hata verilir
if not params:
print "<erreur>Le parametre [params] est absent<erreur></reponse>"
sys.exit()
# params parametresini işliyoruz
#print "alınan parametreler --> %s\n" %(params)
items=params[0].strip().lower().split(',')
# sadece 3 alan olmalı
if len(items)!=3:
print "<erreur>[%s] : nombre de parametres invalide</erreur></reponse>" % (params[0])
sys.exit()
# ilk parametre (medeni durum) evet/hayır şeklinde olmalıdır
marie=items[0].strip()
if marie!="oui" and marie != "non":
print "<erreur>[%s] : 1er parametre invalide</erreur></reponse>\n"% (params[0])
sys.exit()
# ikinci parametre (çocuk sayısı) bir tamsayı olmalıdır
match=re.match(r"^\s*(\d+)\s*$",items[1])
if not match:
print "<erreur>[%s] : 2ieme parametre invalide</erreur></reponse>\n"% (params[0])
sys.exit()
enfants=int(match.groups()[0])
# üçüncü parametre (maaş) bir tamsayı olmalıdır
match=re.match(r"^\s*(\d+)\s*$",items[2])
if not match:
print "<erreur>[%s] : 2ieme parametre invalide</erreur></reponse>\n"% (params[0])
sys.exit()
salaire=int(match.groups()[0])
# vergi hesaplanır
impot=metier.calculer(marie,enfants,salaire)
# sonuç döndürülür
print "<impot>%s</impot></reponse>\n" % (impot)
# son
Notlar:
Bu web hizmeti, önceki hizmetten yalnızca yanıtının niteliği bakımından farklılık gösterir:
Hata durumunda <reponse><erreur>msg</erreur></reponse> yerine <erreur>msg</erreur>
Vergi hesaplanabildiyse <impot>valeur</impot> yerine <reponse><impot>valeur</impot></reponse>
15.2. Programlanmış istemci
Müşterimiz, web hizmeti tarafından gönderilen XML yanıtını analiz etmelidir. XML belgesinin analizinde görülenleri burada da uygularız.
Program (client_impots_web_02)
# -*- coding=utf-8 -*-
import httplib,urllib,re
import xml.sax, xml.sax.handler
# yönetim sınıfı XML
class XmlHandler(xml.sax.handler.ContentHandler):
# başlangıç etiketiyle karşılaşıldığında çağrılan işlev
def startElement(self,name,attributs):
# geçerli öğe kaydedilir
global elementcourant
elementcourant=name.strip().lower()
# bitiş etiketiyle karşılaşıldığında çağrılan işlev
def endElement(self,name):
# hiçbir işlem yapılmaz
pass
# veri yönetimi işlevi
def characters(self,data):
# veriler
global elementcourant,elements
# veriler alınır
match=re.match(r"^\s*(.+?)\s*$",data)
if match:
elements[elementcourant]=match.groups()[0].lower()
def getResultatsXml(reponse):
# yanıt analiz edilir XML
xml.sax.parseString(reponse,XmlHandler())
# sonuçlar veriliyor
if elements.has_key('erreur'):
return (elements['erreur'],"")
else:
return ("",elements['impot'])
# ------------------------------------------------------------ ana
# sabitler
HOST="localhost"
URL="/cgi-bin/impots_web_02b.py"
data=("oui,2,200000","non,2,200000","oui,3,200000","non,3,200000","x,y,z,t","x,2,200000", "oui,x,200000","oui,2,x");
# global değişkenler
elementcourant=""
elements={}
# bağlantı
connexion=httplib.HTTPConnection(HOST)
# izleme
#connexion.set_debuglevel(1)
# sunucuya gönderilecek veriler üzerinde döngü yapılıyor
for params in data:
# parametreler sunucuya gönderilmeden önce kodlanmalıdır
parametres = urllib.urlencode({'params': params})
# isteğin gönderilmesi
connexion.request("POST",URL,parametres)
# yanıtın işlenmesi (XML akışı)
reponse=connexion.getresponse().read()
# xml dosyasının işlenmesi
(erreur,impot)=getResultatsXml(reponse)
if not erreur:
print "impot[%s]=%s" % (params,impot)
else:
print "erreur[%s]=%s" % (params,erreur)
Notlar:
- web hizmetinin XML akışı, getResultatsXml işlevi tarafından işlenir (60. satır);
-
- satır: getResultatsXml işlevi;
- satır 31: web hizmetinin XML yanıtı, satır 6'da tanımlanan XmlHandler sınıfının bir örneği tarafından analiz edilir;
-
- satır: XmlHandler sınıfı, startElement, endElement ve characters adlı 3 yöntemi uygular. Bu 3 yöntem yardımıyla bir sözlük oluşturulur. Anahtarlar, <erreur> ve <impot> etiketlerinin adlarıdır; değerler ise bu iki etikete ait verilerdir;
- 33-36. satırlar: getResultatsXml işlevi, 2 elemanlı bir tuple döndürür:
- (erreur,""), XML akışının analizinde <erreur> etiketinin varlığı tespit edilirse. Bu durumda erreur, bu etiketin içeriğini temsil eder;
- ("",impot), XML akışının analizinde <impot> etiketinin varlığı tespit edilmişse. Bu durumda impot, bu etiketin içeriğini temsil eder.
-
- satır: getResultatsXml işlevinin sonucu alınır ve 61-64. satırlarda işlenir.

