Création bdd à partir d'un fichier XML

kaya57200 Messages postés 18 Date d'inscription mardi 8 décembre 2009 Statut Membre Dernière intervention 23 décembre 2009 - 8 déc. 2009 à 22:23
sahouma34 Messages postés 1 Date d'inscription dimanche 30 novembre 2008 Statut Membre Dernière intervention 25 janvier 2010 - 25 janv. 2010 à 22:24
Bonjour,

Je souhaite créer ma base de donnée ( création des tables + remplissage des champs ) à partir d'un fichier XML qui pourra être modifié.

C'est le seul point noir de mon projet de commerce électronique.

Merci d'avance pour vos idées.

34 réponses

kaya57200 Messages postés 18 Date d'inscription mardi 8 décembre 2009 Statut Membre Dernière intervention 23 décembre 2009
9 déc. 2009 à 21:41
Ok je vois un peu, je dis bien un peu, mieux le fonctionnement de SXE, c'est mon premier cours de PHP donc toute la partie Objet est passée à la trappe.

Ma table rubrique ressemble un peu à ca:

id_rubrique | nom_rubrique | id_sup

1 Les Bécanes NULL
2 Les accessoires NULL
3 Les sportives 1
4 Les roadsters 1
5 roadster anglais 4
6 sportive jap 3

Ainsi de suite.

Je vais essayer de jouer un peu avec le SXE, je vois vite fait comment formuler mes requêtes SQL pour remplir mes tables par contre si mon prof s'amuse à rajouter des propriétés dans son XML ca va être drôle...
0
kaya57200 Messages postés 18 Date d'inscription mardi 8 décembre 2009 Statut Membre Dernière intervention 23 décembre 2009
9 déc. 2009 à 22:23
Non en fait, rien n'y fait...

Je commence à cèder à la panique ^^, si mon prof rajoute des propriétés je ne vois pas comment réagir

- créer une nouvelle table attribut ? modifier ma table produit ?
- puis dans ma partie recherche avancée, je dois adapter toute ma recherche en fonction des nouvelles propriétés mais dans le cas ou il n'aurait rien rajouter comme propriété il se passe quoi sur ma page ?
- Même problème pour afficher un produit.

Je me sens vraiment perdu en fait...
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
9 déc. 2009 à 22:25
S'il rajoute des propriétés dans son XML, c'est pas un soucis : les premières indications que je te donnais concernant la gestion des propriété permet de gérer ça facilement.

Ainsi, pour les propriétés obligatoires, tu sais desquelles il s'agit : quand tu les rencontres, tu connais la valeur du champ pour insérer le produit dans la table.
Pour les propriétés inconnues, il va falloir :
- vérifier si la propriété existe ou non dans la table (récupérer son ID si oui, l'insérer et récupérer son ID si non)
- insérer dans la table de jointure attribut-produit l'id du produit, l'id de la propriété (= de l'attribut) et la valeur (le nom du fichier photo par exemple)
C'est tout.

Pour revenir à la création du XML à partir des rubriques... Ta table n'est pas correctement construite, parce qu'elle ne prend pas en compte une contrainte pourtant manifeste dans le fichier XML : une rubrique peut avoir plusieurs parents. Telle que ta table est faite, une rubrique ne peut avoir qu'une seule rubrique parent, à moins de dupliquer son nom dans la table, ce qui conduirait à une incohérence de la base de données : tu aurais plusieurs données portant le même nom (car la même rubrique) mais avec des ID différents.
En analyse, la relation rubrique-rubrique_parent est une relation n,n : une rubrique peut avoir plusieurs enfants, un enfant peut avoir plusieurs parents.
Conceptuellement, l'élément Rubrique est relié à lui-même. Physiquement, une table supplémentaire matérialise cette relation. Ca donne :

RUBRIQUE
- id_rubrique
- nom_rubrique

RUBRIQUE_REL
- id_rubrique
- id_rubrique_parent

Dans cette table RUBRIQUE_REL, l'ID d'une rubrique peut se retrouver plusieurs fois dans chacune des deux colonnes, mais jamais les deux sur la même ligne (une rubrique ne pouvant être sa propre fille !)
Pour récupérer la liste des rubriques et de leurs parents, c'est un peu moins évident, mais c'est quand même tout à fait faisable (avec un peu d'algo, on s'en sort).

Il faut faire une requête qui porte sur les deux tables. On va récupérer dans cette requête plusieurs fois l'id de la rubrique courante : c'est normal si elle a plusieurs parents. Essaie cette requête, tu vas être surpris ;)
SELECT r.*, rr.id_rubrique_parent AS id_parent FROM rubrique r LEFT JOIN rubrique_rel rr ON r.id_rubrique=rr.id_rubrique ORDER BY r.id_rubrique

J'ai créé les tables en local, avec les données que tu m'as données. La requête me retourne, avec mes deux tables différentes de la tienne, exactement les mêmes résultats que si j'avais fait un select * sur ta table. La différence : je peux avoir plusieurs parents pour une même rubrique, et une rubrique peut avoir plusieurs enfants.
Voici le code SQL pour construire les tables comme je les ai faites chez moi :

CREATE TABLE IF NOT EXISTS `rubrique` (
  `id_rubrique` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `nom_rubrique` varchar(255) COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`id_rubrique`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=7 ;

INSERT INTO `rubrique` (`id_rubrique`, `nom_rubrique`) VALUES (1, 'Les bécanes'), (2, 'Les accessoires'), (3, 'Les sportives'),
(4, 'Les roadsters'), (5, 'Roadsters anglais'), (6, 'Sportives japonaises');

CREATE TABLE IF NOT EXISTS `rubrique_rel` (
  `id_rubrique` int(10) unsigned NOT NULL,
  `id_rubrique_parent` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id_rubrique`,`id_rubrique_parent`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO `rubrique_rel` (`id_rubrique`, `id_rubrique_parent`) VALUES (3, 1), (4, 1), (5, 4), (6, 3);


J'ai rajouté une rubrique "Décorations pour sportives" (oui, c'est farfelu, on s'en fout :) ). Dans la table de relation, je lui ai assigné comme parents les rubriques 2 et 6 (accessoires et sportives).
Quand je réexécute la requête SELECT de tout à l'heure, j'ai dans mon résultat, deux fois la rubrique "Décorations pour sportives", avec comme id_parent les 2 et 6. Normal.
Avant de parcourir le résultat de la requête, il faut définir une variable "temporaire" dans laquelle tu vas stocker l'ID de la rubrique en cours et l'initialiser à 0 (zéro) : les ID auto-incrémentiels commencent à 1, il faut mettre une valeur qui ne PEUT PAS exister dans la base, à cause de ce qui suit. Tu dois aussi garder une trace des rubriques
Au début de la boucle qui récupère la ligne suivante, tu compares la valeur de l'id de la rubrique et celui stocké dans la variable temporaire. S'il est différent (ce qui est forcément le cas à la première itération puisqu'il vaut 0), alors on a une nouvelle rubrique : on peut la décrire dans le fichier XML et inscrire le nom de la rubrique parent.
Si l'id dans la variable temporaire et l'id de la rubrique sont identiques, alors il s'agit toujours de la même rubrique, qui a une autre rubrique parent.
Pour chaque rubrique (donc quand la variable temp et l'id de la rubrique courante sont différents) on stocke dans un tableau l'id et le nom de la rubrique, ça permet de récupérer le nom plus tard, notamment quand on fait référence à une rubrique parent (qui doit théoriquement avoir déjà été lue dans le résultat de la requête). Le tableau des rubriques doit être indexé numériquement, avec comme index l'id des rubriques ; schématiquement : $tableau_rubriques[$id_rubrique] = $nom_rubrique;
Donc quand les deux id sont identiques, on a une nouvelle rubrique parent pour la rubrique en cours : on connait son nom grâce au tableau dans lequel on garde la trace des rubriques.
Donc quand on passe à une nouvelle rubrique, si l'id précédent est différent de 0 (si ce n'est pas la première de la liste) on ferme les balises de la rubrique précédente dans le XML et on ouvre celle de la nouvelle.
A la fin (après la boucle), on ferme simplement la rubrique en cours dans le XML.

J'ai essayé de faire le plus clair possible, j'espère que ça l'est donc...

C'est pas la première fois que j'explique ça sur phcps, je crois que je vais devoir faire un article sur mon blog pour expliquer ça de manière générale ^^ Et c'est pas la première fois que je dis que je vais faire un article sur mon blog à propos d'un sujet que je traite plusieurs fois... :/ Arf.

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
9 déc. 2009 à 22:38
Arf, t'as posté un nouveau message entre temps...
T'as pas de raison de paniquer.
Keep cool, reste zen.

Donc si ton prof rajoute des propriétés et que tu suis mes recommandations tant pour la conception de la base que pour son utilisation avec le code PHP, tu pourras les rajouter sans difficulté et gérer ça tranquillement les doigts dans le nez.

D'après ce que j'ai compris de ton sujet, la recherche ne doit pas porter sur les propriété facultatives, mais uniquement sur la description qui est considérée comme une liste de mot-clés (quasiment mot pour mot ce qui est dit dans le sujet).

Pour afficher un produit, tu fais une requête sur la table produit et tu récupères les champs, normalement. Tu as ainsi les propriétés obligatoires. Tu fais une autre requête sur la table attributs avec une jointure sur la table attribut-produit (histoire de ne prendre que les attributs qui correspondent au produit demandé) et tu récupères ainsi la liste des attributs optionnels, que tu peux alors afficher tranquillement, sous la forme :
nom : valeur
Pour certains attributs, tu peux avoir un comportement spécifique, comme la photo descriptive : au lieu d'afficher le nom (qui sera "Photo descriptive") et la valeur ("BarreDeFaire.jpg") tu affiches l'image, avec une balise en utilisant la valeur comme source de l'image (en adaptant si besoin le chemin du répertoire où tu stockes les photos des produits). Il ne me semble pas qu'il soit mentionné que les photos sont fournies par le document XML (sinon il y aurait au moins un exemple), donc tu n'as pas à te soucier de ça.

Est-ce que tu paniques encore ?

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
kaya57200 Messages postés 18 Date d'inscription mardi 8 décembre 2009 Statut Membre Dernière intervention 23 décembre 2009
9 déc. 2009 à 22:40
Mais la je deviens complètement fou ! En fait tout le site que j'ai déjà fait est complètement faux a cause de ce problème de rubriques....



Je vais voir si c'est facilement modifiable dans mon code sinon tempi pour cette close de l'ennoncé, j'ai encore un projet de C++ et de Java qui m'attendent jusqu'au 15 janvier...
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
9 déc. 2009 à 22:45
Ben sinon, laisse en l'état, mais ça pourrait poser problème si le fichier de ton prof considère que certaines rubriques peuvent avoir plusieurs parents, comme c'est le cas dans l'exemple... Ca ferait planter ton import de données.

Cela dit, dans les deux cas, tu peux quand même gérer la liste des rubriques pour l'criture du XML comme je te l'ai dit (mais bon, si ton code marche, t'es pas obligé de le modifier, hein, je ne fais que t'indiquer comment faire ça avec une seule requête pour économiser des ressources et éviter une fonction récursive).

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
kaya57200 Messages postés 18 Date d'inscription mardi 8 décembre 2009 Statut Membre Dernière intervention 23 décembre 2009
9 déc. 2009 à 22:59
Oui je pense que je vais laisser ca dans l'état, je vais demander a mon prof ce qu'il en pense vendredi, car la table rubrique c'est lui qui ma dit de la faire comme ca.

Ce qui m'énerves c'est que j'aimerai bien faire tout comme il faut dans les règles de l'art mais bon... En première année en cours de SQL c'est a peine si on a vu les jointure entres les tables donc bon vivent les lacunes pour ce projet.

Demain, je termine mon rapport d'IHM donc j'aurais sûrement pas le temps de bosser le PHP. Je posterai l'avis de mon prof donc seulement vendredi, d'ici la silence radio ^^

En tout cas merci encore pour ton aide et ta réactivité.
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
9 déc. 2009 à 23:22
En cours de SQL, vous avez pas vu des méthodes d'analyse comme Merise ?
Si ton prof t'a dit de faire ta table rubrique comme ça, alors... Mais c'est bizarre, parce que c'est pas cohérent avec le XML qu'il fournit dans le sujet.

Ah et pis t'inquiète pas : on ne peut JAMAIS rien faire comme on veut, tout bien comme il faut, dans les règles de l'art : on est toujours obligé de bâcler certains points d'un développement pour y revenir plus tard, en générale à l'arrache encore une fois... Moi ça me fait chier, je sais pas travailler rapidement à l'arrache, je sais faire que du super propre, documenté, élaboré, réfléchi tout ça... Mais c'est dur dans ce métier...

Courage !

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
kaya57200 Messages postés 18 Date d'inscription mardi 8 décembre 2009 Statut Membre Dernière intervention 23 décembre 2009
22 déc. 2009 à 14:47
Salut,

Bon après une dernière semaine d'exams, je réattaques ce projet.

J'ai régler le problème des rubriques multiples mais je n'y arrive toujours pas avec le XML

Je voudrais pour chaque produit un tableau associatif
NomPropriété -> Valeur pour pouvoir vérifier que tous les champs sont bons et pour pouvoir remplir ma base de donnée

Le probleme cest que j'ai toujours des object SimpleXMLElement dedans et pas des strings.
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
22 déc. 2009 à 14:58
Un objet SimpleXMLElement() implémente la fonction __toString() et peut donc être converti en chaîne grâce au transtypage : (string) avec les parenthèses
Cela permet de ne pas modifier le type de l'objet, mais uniquement de la valeur retournée.

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
kaya57200 Messages postés 18 Date d'inscription mardi 8 décembre 2009 Statut Membre Dernière intervention 23 décembre 2009
22 déc. 2009 à 19:59
Bon j'ai reussi a tout faire, j'ai juste encore un soucis pour l'exportation des données vers XML:

J'ai des résultats farfelus avec mes rubriques sup, parfois deux fois la même rubrique sup etc...

Sinon le reste fonctionne
0
kaya57200 Messages postés 18 Date d'inscription mardi 8 décembre 2009 Statut Membre Dernière intervention 23 décembre 2009
23 déc. 2009 à 10:57
Derniere petite question: Dans mon entête j'ai bien
<?xml version="1.0" encoding="ISO-8859-1"?>

cependant quand je remplis ma bdd j'ai quand meme des mots où les accents sont mals codés.
0
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
23 déc. 2009 à 14:29
Salut,

Il faut indiquer à MySQL l'encodage de la connexion, si celui-ci diffère de l'encodage par défaut, avec les deux requêtes suivantes (ou peut-être qu'une seule suffit) :
SET NAMES latin1;
SET CHARACTER SET latin1


Référence : http://dev.mysql.com/doc/refman/5.0/fr/charset-connection.html

Il est aussi possible d'encoder/décoder vers/depuis utf8 avec utf8_encode() et utf8_decode(), selon le jeu de caractères du fichier lu (parce que suivant l'éditeur de texte, le fichier tapé à la main peut être encodé en ISO-8859 ou en UTF8, il faut prendre ce paramètre en compte...)

--
Neige

Souvent la réponse à votre question se trouve dans la doc. Commencez par là ;)
0
sahouma34 Messages postés 1 Date d'inscription dimanche 30 novembre 2008 Statut Membre Dernière intervention 25 janvier 2010
25 janv. 2010 à 22:24
bonjour,

j ai bien le meme probleme!!?
est ce que je peux avoir un exemple du code de la creation de la base de donnee a partir du fichier xml?
merci
0
Rejoignez-nous