67. Gestion d’une librairie en ligne

67.1. Présentation

Le principe de la librairie est simple, un serveur fournit une liste de livres sous forme d’un document XML. Un client transforme alors ce document en pages HTML.

Vous allez devoir créer un modèle de document pour vos échanges, réaliser le service qui fournit le document XML et implémenter le client qui gère la transformation avec XSLT.

67.2. Le modèle de document

Votre modèle pourra contenir les informations suivantes pour chaque livre :

67.3. Service

Il doit permettre de générer un document XML. Pour simuler la source de données vous pouvez simplement utiliser un tableau avec les informations qui vous semblent nécessaires.

Le code suivant donne un exemple de ce que pourrait être ce tableau :

$sourceDonnees = array(
	array(
		"titre" => "livre A",
		"auteur" => "auteur A",
		"promotion" => 10,
		"resume" => "bla bla bla",
		"prix" => 40.50,
		"isbn" => "2-84177-089-3"
	),
		array(
		"titre" => "livre B",
		"auteur" => "auteur B",
		"promotion" => 15,
		"resume" => "bla bla bla",
		"prix" => 29.90,
		"isbn" => "2-84177-089-4"
	),
	array(
		"titre" => "livre N",
		"auteur" => "auteur N",
		"promotion" => 5,
		"resume" => "bla bla bla",
		"prix" => 50,
		"isbn" => "2-84177-089-N"
	)
);

La validation du document est importante car elle est la garantie de ce que vous envoyez, ne la négligez pas. Ceci est d’autant plus important si le client et le serveur sont développés en parallèle.

67.4. Le site Web

La transformation du document se fera bien évidement avec XSLT.

Une première page présentera les livres sous forme d’une liste, avec la possibilité de les trier selon différents critères (par exemple le prix et la catégorie).

Si vous disposez d’assez de temps, vous pouvez créer une page de détail des livres qui permette en plus de naviguer d’annonce en annonce à l’aide de liens "précédent" et "suivant".

67.5. Travail réalisé

Voici le contenu du travail réalisé. Il se décompose en plusieurs fichiers.

Comme il n'est pas possible pour moi de vous mettre un lien direct vers un serveur distant opérationnel, vous devrez vous contenter d'une capture d'écran du rendu final.

Figure 59. Projet librairie en ligne

67.5.1. librairie.xsd

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<xsd:element name="titre" type="xsd:string" />
	<xsd:element name="auteur" type="xsd:string" />
	<xsd:element name="resume" type="xsd:string" />
	<xsd:element name="prix" type="xsd:string" />
	<xsd:element name="categorie" type="xsd:string" />
	
	<xsd:element name="reduction">
		<xsd:complexType>
			<xsd:attribute name="pourcentage" type="xsd:int" use="required" />
		</xsd:complexType>
	</xsd:element>
	
	<xsd:element name="librairie">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:element ref="livre" maxOccurs="unbounded" />
			</xsd:sequence>
		</xsd:complexType>
	</xsd:element>
	
	<xsd:element name="livre">
		<xsd:complexType>
			<xsd:sequence>
				<xsd:element ref="titre" />
				<xsd:element ref="auteur" />
				<xsd:element ref="resume" />
				<xsd:element ref="prix" />
				<xsd:element ref="reduction" minOccurs="0" />
				<xsd:element ref="categorie" />
			</xsd:sequence>
			<xsd:attribute name="isbn" type="xsd:string" use="required" />
		</xsd:complexType>
	</xsd:element>
</xsd:schema>

67.5.2. librairie.php

<?php
	$sortingItem = isset($_GET['sortingItem']) ? $_GET['sortingItem'] : "" ;

	$sourceDonnees = array(
		array(
			"titre" => "La jalousie des élus ",
			"auteur" => "Greribard Buwyth",
			"reduction" => 10,
			"resume" => "Sermone conpulsus denique appellant ad indumentum nomine idem denique appellant Graeco speciem inductus perurgebant confessisque Maras haec conpulsus prolatae Graeco.",
			"prix" => 20.50,
			"isbn" => "2-15687-089-3",
			"categorie" => "Polar"
		),
		array(
			"titre" => "Obsolescence des pendules",
			"auteur" => "Gwalim Adrigokor",
			"reduction" => 15,
			"resume" => "Ponderum arta ad tamen discursatore explicare rupium prensando clivos prensando gressus: aut ad hoste invia.",
			"prix" => 29.90,
			"isbn" => "1-89157-089-4",
			"categorie" => "Thriller"
		),
		array(
			"titre" => "La belle des pages",
			"auteur" => "Astiretram Glayli",
			"reduction" => 15,
			"resume" => "Est te equidem doctrinis eruditi politus probo tenent cetero quas te instructior aut equidem studiis.",
			"prix" => 19.90,
			"isbn" => "2-54197-099-4",
			"categorie" => "Policier"
		),
		array(
			"titre" => "La tendresse de Paris",
			"auteur" => "Gwirashv Nydedriwyth",
			"reduction" => 15,
			"resume" => "Indigna ad id statuas Constantii commotus decere docens advocatos quidem fieri perferens cogitari in vocis.",
			"prix" => 29.90,
			"isbn" => "2-84847-012-1",
			"categorie" => "Policier"
		),
		array(
			"titre" => "Le futur des araignées",
			"auteur" => "Haeth Helakor",
			"reduction" => 15,
			"resume" => "Verborum interpretemur sermonisque ex qui sermonisque virosque Galos virtutem consuetudine Galos nostri verborum magnificentia eam.",
			"prix" => 45.90,
			"isbn" => "1-95477-039-4",
			"categorie" => "Sciences"
		),
		array(
			"titre" => "L'exécution des veuves",
			"auteur" => "Onuvudd Praowin",
			"reduction" => 15,
			"resume" => "Non enim fructus enim sic sed beneficium eius liberalitatem eius benefici liberalitatem beneficium sumus) mercedis.",
			"prix" => 10.50,
			"isbn" => "2-00017-019-4",
			"categorie" => "Thriller"
		),
		array(
			"titre" => "La vie d'une audacieuse",
			"auteur" => "Nagnar Gegnar",
			"reduction" => 5,
			"resume" => "Ad nitidis nitidis cedentem habens et et exaedificavit ad Caesaream et itidemque exaedificavit exaedificavit exaedificavit.",
			"prix" => 30,
			"isbn" => "8-89777-088-C",
			"categorie" => "Polar"
		)
	);
	
	function &generateLibrairieXML(&$sourceDonnees) {
		$xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
		$xml .= "<librairie>";

		foreach ($sourceDonnees as $monLivre) {
			$xml .= "<livre isbn=\"".$monLivre['isbn']."\">";
				$xml .= "<titre>".$monLivre['titre']."</titre>";
				$xml .= "<auteur>".$monLivre['auteur']."</auteur>";
				$xml .= "<resume>".$monLivre['resume']."</resume>";
				$xml .= "<prix>".$monLivre['prix']."</prix>";
				if ( isset($monLivre['reduction']) and !empty($monLivre['reduction']) ) {
					$xml .= "<reduction pourcentage=\"".$monLivre['reduction']."\" />";
				}
				$xml .= "<categorie>".$monLivre['categorie']."</categorie>";
			$xml .= "</livre>";
		}
		$xml .= "</librairie>";
		
		return $xml;
	}
	
	$xml =& generateLibrairieXML($sourceDonnees); // Génération XML.
	$documentXML = DOMDocument::loadXML($xml); // Chargement du source.

	if ($documentXML->schemaValidate("librairie.xsd")) { // Vérification validité XSD.
		$processeurXSLT = new XSLTProcessor();
		$processeurXSLT->importStyleSheet(DOMDocument::load("librairie.xsl"));
		$processeurXSLT->setParameter('xsl', 'sort', $sortingItem);
		echo $processeurXSLT->transformToXML($documentXML);
	} else {
		die("Erreur de génération XML.");
	}
?>

67.5.3. librairie.xsl

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="html" encoding="UTF-8" />
	
	<xsl:template match="/">
		<html>
			<head>
				<title>Librairie en ligne</title>
			</head>
			<body>
				<h2>Liste des livres disponibles :</h2>
				<xsl:apply-templates />
			</body>
		</html>
	</xsl:template>
	
	<xsl:template match="/librairie">
		<table border="1">
			<tr>
				<td><a href="./librairie.php?sortingItem=titre">Titre</a></td>
				<td><a href="./librairie.php?sortingItem=auteur">Auteur</a></td>
				<td>ISBN</td>
				<td>Catégorie</td>
				<td>Résumé</td>
				<td><a href="./librairie.php?sortingItem=prix">Prix</a></td>
				<td><a href="./librairie.php?sortingItem=reduction">Réduction</a></td>
			</tr>
			
			<xsl:choose>
				<xsl:when test="$sort='titre'">
					<xsl:for-each select="livre">
						<xsl:sort select="titre" data-type="text" />
						<tr>
							<td><xsl:value-of select="./titre" /></td>
							<td><xsl:value-of select="./auteur" /></td>
							<td><xsl:value-of select="@isbn" /></td>
							<td><xsl:value-of select="./categorie" /></td>
							<td><xsl:value-of select="./resume" /></td>
							<td><xsl:value-of select="./prix" /></td>
							<td><xsl:value-of select="./reduction/@pourcentage" /><xsl:text>%</xsl:text></td>
						</tr>
					</xsl:for-each>
				</xsl:when>
				<xsl:when test="$sort='auteur'">
					<xsl:for-each select="livre">
						<xsl:sort select="auteur" data-type="text" />
						<tr>
							<td><xsl:value-of select="./titre" /></td>
							<td><xsl:value-of select="./auteur" /></td>
							<td><xsl:value-of select="@isbn" /></td>
							<td><xsl:value-of select="./categorie" /></td>
							<td><xsl:value-of select="./resume" /></td>
							<td><xsl:value-of select="./prix" /></td>
							<td><xsl:value-of select="./reduction/@pourcentage" /><xsl:text>%</xsl:text></td>
						</tr>
					</xsl:for-each>
				</xsl:when>
				<xsl:when test="$sort='prix'">
					<xsl:for-each select="livre">
						<xsl:sort select="prix" data-type="number" />
						<tr>
							<td><xsl:value-of select="./titre" /></td>
							<td><xsl:value-of select="./auteur" /></td>
							<td><xsl:value-of select="@isbn" /></td>
							<td><xsl:value-of select="./categorie" /></td>
							<td><xsl:value-of select="./resume" /></td>
							<td><xsl:value-of select="./prix" /></td>
							<td><xsl:value-of select="./reduction/@pourcentage" /><xsl:text>%</xsl:text></td>
						</tr>
					</xsl:for-each>
				</xsl:when>
				<xsl:when test="$sort='reduction'">
					<xsl:for-each select="livre">
						<xsl:sort select="reduction/@pourcentage" data-type="number" order="descending" />
						<tr>
							<td><xsl:value-of select="./titre" /></td>
							<td><xsl:value-of select="./auteur" /></td>
							<td><xsl:value-of select="@isbn" /></td>
							<td><xsl:value-of select="./categorie" /></td>
							<td><xsl:value-of select="./resume" /></td>
							<td><xsl:value-of select="./prix" /></td>
							<td><xsl:value-of select="./reduction/@pourcentage" /><xsl:text>%</xsl:text></td>
						</tr>
					</xsl:for-each>
				</xsl:when>
				<xsl:otherwise>
					<xsl:for-each select="livre">
						<tr>
							<td><xsl:value-of select="./titre" /></td>
							<td><xsl:value-of select="./auteur" /></td>
							<td><xsl:value-of select="@isbn" /></td>
							<td><xsl:value-of select="./categorie" /></td>
							<td><xsl:value-of select="./resume" /></td>
							<td><xsl:value-of select="./prix" /></td>
							<td><xsl:value-of select="./reduction/@pourcentage" /><xsl:text>%</xsl:text></td>
						</tr>
					</xsl:for-each>
				</xsl:otherwise>
			</xsl:choose>
		</table>
	</xsl:template>
</xsl:stylesheet>

67.5.4. Les sources de l'application

L'archive zippée est téléchargeable ici-même.