13. IMPOTS Ejercicio con XML
En este ejercicio, que ya hemos estudiado muchas veces, el servidor devuelve los resultados al cliente en forma de flujo XML.
13.1. El servidor (impots_05B_web)
El servicio web de cálculo de impuestos escrito anteriormente tiene una arquitectura en capas:
![]() |
En el ejemplo anterior, el servicio web envió una de las dos líneas siguientes a sus clientes:
No se trata de un documento XML bien formado porque carece de etiqueta raíz. El nuevo servicio web enviará su respuesta en el siguiente formato:
o
En ambos casos, la respuesta es un documento XML bien formado que puede ser procesado por el módulo [simpleXML].
En la arquitectura de tres niveles, sólo es necesario modificar la capa [web]. Su código [impots_05B_web] pasa a ser el siguiente:
1. <?php
2.
3. // business layer
4. require_once "impots_05_business.php";
5.
6. // error handling
7. ini_set("display_errors", "off");
8.
9. // UTF-8 header
10. header("Content-Type: text/plain; charset=utf-8");
11.
12. // ------------------------------------------------------------------------------
13. // the tax web service
14. // definition of constants
15. $HOST = "localhost";
16. $PORT = 3306;
17. $DATABASE = "dbimpots";
18. $USER = "root";
19. $PWD = "";
20. // The data needed to calculate the tax has been placed in the MySQL table $TABLE
21. // belonging to the $BASE database. The table has the following structure
22. // limits decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
23. // the parameters for taxable individuals (marital status, number of children, annual salary)
24. // are sent by the client in the form params=marital status, number of children, annual salary
25. // the results (marital status, number of children, annual salary, tax due) are returned to the client
26. // in the form <tax>tax</tax>
27. // or in the form <error>error</error>, if the parameters are invalid
28. // retrieve the [business] layer from the session
29. session_start();
30. if (!isset($_SESSION['business'])) {
31. // instantiate the [dao] layer and the [business] layer
32. try {
33. $_SESSION['metier'] = new ImpotsMetier(new ImpotsDaoWithMySQL($HOST, $PORT, $BASE, $USER, $PWD));
34. } catch (ImpotsException $ie) {
35. print "<response><error>Error: " . utf8_encode($ie->getMessage() . "</error></response>");
36. exit;
37. }
38. }
39. $job = $_SESSION['job'];
40.
41. // retrieve the line sent by the client
42. $params = utf8_encode(htmlspecialchars(strtolower(trim($_POST['params']))));
43. //print "parameters received --> $params\n";
44. $items = explode(",", $params);
45. // there must be exactly 3 parameters
46. if (count($items) != 3) {
47. print "<response><error>[$params]: number of invalid parameters</error></response>\n";
48. exit;
49. }//if
50. // the first parameter (marital status) must be yes/no
51. $married = trim($items[0]);
52. if ($married != "yes" and $married != "no") {
53. print "<response><error>[$params]: Invalid first parameter</error></response>\n";
54. exit;
55. }//if
56. // the second parameter (number of children) must be an integer
57. if (!preg_match("/^\s*(\d+)\s*$/", $items[1], $fields)) {
58. print "<response><error>[$params]: Invalid second parameter</error></response>\n";
59. exit;
60. }//if
61. $children = $fields[1];
62. // the third parameter (salary) must be an integer
63. if (!preg_match("/^\s*(\d+)\s*$/", $items[2], $fields)) {
64. print "<response><error>[$params]: Invalid third parameter</error></response>\n";
65. exit;
66. }//if
67. $salary = $fields[1];
68. // calculate the tax
69. $tax = $occupation->calculateTax($married, $children, $salary);
70. // return the result
71. print "<response><tax>$tax</tax></response>\n";
72. // end
73. exit;
El formato de la respuesta del servicio web se modifica en las líneas 35, 47, 53, 58, 64 y 71.
13.2. El cliente (client_impots_05b_web)
El cliente se modifica para tener en cuenta el nuevo formato de respuesta. Utilizamos [simpleXML] para procesarlo:
1. <?php
2.
3. // tax client
4. // error handling
5. ini_set("display_errors", "off");
6.
7. // ---------------------------------------------------------------------------------
8. // a class of utility functions
9. class Utilities {
10. ...
11. }
12.
13. // main -----------------------------------------------------
14. // definition of constants
15. $DATA = "data.txt";
16. $RESULTS = "results.txt";
17. // server data
18. $HOST = "localhost";
19. $PORT = 80;
20. $serverUrl = "/web-examples/taxes_05B_web.php";
21.
22. ...
23. exit;
24.
25. function calculateTax($HOST, $PORT, $serverUrl, &$cookie, $params) {
26. // connects the client to ($HOST, $PORT, $serverUrl)
27. // sends the $cookie if it is not empty. $cookie is passed by reference
28. // sends $params to the server
29. // processes the result line
30. ...
31. // read the result line
32. $line = fgets($connection, 1000);
33. // close the connection
34. fclose($connection);
35. // calculate result
36. $xml = new SimpleXMLElement($line);
37. $error = isset($xml->error) ? $xml->error : "";
38. $tax = isset($xml->tax) ? $xml->tax : "";
39. // return
40. return array($error, $tax);
41. }
- línea 32: se lee la respuesta del servidor. Se trata de un documento XML.
- línea 36: Se construye un objeto SimpleXML a partir del documento XML recibido.
- línea 37: cualquier mensaje de error
- línea 38: importe del impuesto, en su caso
