importation de données issues d'un fichier XML-TEI dans une BD mySQL

Eléphanteau du PHP | 18 Messages

23 oct. 2015, 14:58

Bonjour,

J'espère ne pas me tromper de forum...
L'objectif de ce message est de savoir quelle est la meilleure méthode d'importation de fichier XML-TEI dans une base de données mySQL.

Où se trouvent mes données et de quelles natures sont-elles ? Mes données se trouvent dans deux projets distincts qui pourraient être considérés comme indépendants (jusqu'à un certain point pour les données XML-TEI) :
1. J'ai un fichier XML-TEI dans lequel j'encode au fur et à mesure un corpus de textes, à des fins d'édition numérique pour mettre en avant des occurrences lexicales. Généralement, il y a un utilisateur par fichier.
2. Par ailleurs, j'ai une base de données mySQL dont les données sont affichées via php/xhtml5 dans un navigateur. Ces données sont plurielles et sont issues de plusieurs corpus, saisies par plusieurs utilisateurs. L'objectif est à des fins plutôt statistiques.
Les données majoritairement lexicales (mais pas que) du fichier XML-TEI viendraient donc simplement enrichir la BD mySQL, qui a reçoit par ailleurs des données à partir d'un formulaire.

Je ne souhaite pas importer dans la BD mySQL toutes les données de mon fichier XML-TEI.
Les balises d'encodage de mon fichier XML-TEI ne correspondent malheureusement pas aux titres de mes colonnes dans ma BD mySQL.
Il faut donc que je passe par une étape intermédiaire, une sorte de table de concordance :
Dans mon fichier XML-TEI @type = lexem ce qui équivaut à extractedLexem dans mySQL et ainsi de suite.

J'ai lu la réflexion d'@rthur sur l'importation de données à partir d'un fichier XML faq-tutoriels/importer-des-donnees-xml- ... 43506.html , j'ai cru comprendre que la meilleure méthode est XSLT (ce qui pourrait m'arranger). Cependant, @rthur n'exclut pas la solution PHP. On m'a également suggéré JSON.
Pour choisir la meilleure solution, il faut prendre en considération le moment souhaité pour l'importation :
l'importation de nouvelles données du fichier XML-TEI devra se faire automatiquement à chaque fois qu'une mise à jour du fichier XML-TEI sera faite sur le serveur.
Dans ces conditions, quelle est la meilleure solution selon vous ?

On m'a souvent demandé pourquoi je n'opte pas pour BaseX ou eXist-db : comme précédemment écrit, il s'agit de deux projets en un et à la fois indépendants. Les données saisies dans ma base mySQL ne nécessitent pas un encodage en XML-TEI. Les deux BD (XML native et SGBDR mySQL) sont indépendantes. Cependant les données XML-TEI ont pour fonction d'enrichir la BD mySQL.

En vous remerciant par avance de vos suggestions,

McCallum

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

24 oct. 2015, 00:00

salut,

Le problème des exemples d'@rtur c'est qu'il ne font qu'intégrer les données brutes en base.
De ce que j'ai compris, le fichier va évoluer dans le temps avec ajout de données.
Du coup il te faut gérer le fait que tu ne souhaites pas forcément insérer toutes les données.
Vu comme ça je m'orienterais vers du full php et un cron pour l’exécuter régulièrement.
Les arguments d'@rtur sont toujours bon plus le fichier va être gros plus cela va être long et gourmand en ressource.
Il est possible d'utiliser des requêtes préparées pour vérifier si tu dois ou non insérer l'information et éviter trop de requête gourmande.

Vu la source de données soit tu montes le fichier en mémoire complètement soit tu le lis séquentiellement pour éviter de dépasser la taille mémoire maximum.
quoi qu'il en soit il te faut vérifier la présence d'une ligne existante avant d'insérer et cela tu ne peux le faire avec xslt et le chargement du fichier xml direct.

L'avantage d'utiliser php en cli est que tu vas peux être pouvoir lever la limite mémoire pour te faciliter la tâche.

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 18 Messages

24 oct. 2015, 16:30

Bonjour,

Je te remercie de ta réponse moogli.
Exact, le fichier va évoluer avec le temps.

D'après ta réponse, je n'ai guère le choix à cause de l'execution régulière d'une partie des données :
il te faut vérifier la présence d'une ligne existante avant d'insérer et cela tu ne peux le faire avec xslt et le chargement du fichier xml direct.
Toutefois, comme @rthur et toi vous le soulignez :
plus le fichier va être gros plus cela va être long et gourmand en ressource.
Mon fichier va être effectivement très gros.
Tu proposes du « full php + cron » — on m'avait effectivement parlé de cron — , mais full php est-ce la bonne solution étant donné le côté gourmand des ressources ?
A moins de pouvoir fractionner le contenu des données qui seront exportées à partir du fichier XML, c'est-à-dire :
- dans mon fichier XML, j'ai des attributs @types relatifs à l'analyse grammaticale => un fichier php
- dans mon fichier XML, j'ai des attributs @types relatifs à des anthroponymies => un fichier php
- etc.
Est-ce que c'est possible ?

J'ai lu que JSON pouvait également faire la liaison entre XML et mySQL. Je suis débutante aussi bien en JSON qu'en php (avec quelques notions de syntaxe très sommaire :lol: malgré tout), cependant il semblerait que le JSON soit plus compréhensible pour quelqu'un qui maitrise à peu près correctement XML-TEI. Ton avis ?
L'avantage d'utiliser php en cli est que tu vas peux être pouvoir lever la limite mémoire pour te faciliter la tâche.
Excuse ma question de débutante, est-ce que tu peux développer un peu plus ?

Donc, si j'ai bien compris, pas de XSLT à cause de l'exécution régulière sur le serveur et surtout l'impossibilité de vérifier si la donnée existe déjà — corrige-moi si j'ai mal compris STP.

En te remerciant par avance de de ta réponse,

McCallum

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

28 oct. 2015, 00:21

salut,

xslt c'est puissant mais ne feras une requête sql pour vérifier la présence de la donnée en base ;)
au mieux tu pourrais utiliser XSLT pour "allerger" le fichier et garder que les choses que tu juge indispensable.

Dissocier les type c'est pas forcément mieux sachant que de toute façon tu dois parcourir le fichier complet de toutes façon (cela va aussi permettre de proposer une mise à jour ;) ).
qu'entends tu par gros fichiers ? c'est en méga ou giga octets ?

Tu ne pourras surement pas utiliser simplexml pour charger le fichier s'il est vraiment gros. dans ce cas il faudra le lire au fil de l'eau.
il existe plusieurs façon pour lire et "parser" un fichier xml
http://php.net/manual/fr/refs.xml.php
A priori XMLReader peux t'aider http://php.net/manual/fr/class.xmlreader.php
Après "faut tester" et voir si tu es sur un hébergement mutualisé ou non.

pour ne pas avoir de time out : http://php.net/manual/fr/function.set-time-limit.php

Php n'est pas si gourmand, après tu peux le faire dans autre langage si tu le souhaites mais la limite mémoire sera la et il faut voir si tu pourras l'utiliser.

suivant la fraîcheur des données souhaité et la taille du fichier le calcul du délais entre chaque exécution du cron peux être complexe. (tu ne peux raisonnablement pas penser avoir 2Go de XML traiter toutes les 30s ;) ).

Dernière chose : as tu une autre possibilité pour la source de données ?
C'est con mais parfois faut explorer d'autre.

C'est pas une réponse qui peux t'aider plus que dans la réflexion mais c'est déjà ça.

Il faut que tu test d'utiliser un petit xml pour te faire la main sur le code.
Pour l'insertion en base tu peux utiliser PDO, et une (ou plusieurs) requête(s) préparée(s).

@+
Il en faut peu pour être heureux ......

Eléphanteau du PHP | 18 Messages

28 oct. 2015, 01:07

Bonsoir,

Merci Moogli pour ta réponse détaillée !
qu'entends tu par gros fichiers ? c'est en méga ou giga octets ?
peut-être giga octets car il peut y avoir des images.
il existe plusieurs façon pour lire et "parser" un fichier xml
http://php.net/manual/fr/refs.xml.php
A priori XMLReader peux t'aider http://php.net/manual/fr/class.xmlreader.php
Merci. Costaud à déchiffrer ! enfin, c'est surtout une syntaxe totalement différente du XML-TEI.
Dernière chose : as tu une autre possibilité pour la source de données ?
Je n'ai pas d'autre alternative : je suis philologue et je dois mettre en ligne mon corpus. Ce sont les recommandations non-négociables si on recherche des budgets européens.

J'ai une instance chez Gandi, donc pas encore mon propre serveur.

En tout cas, tu as répondu à ma demande initiale. Je vais éplucher avec attention tous tes liens et très probablement poster à nouveau sur le forum pour avoir de l'aide sur la syntaxe qui diffère des modèles en XML puisque je travaille avec XML-TEI.
Merci pour tes précieux conseils :D

McCallum

Eléphanteau du PHP | 18 Messages

30 oct. 2015, 19:38

Bonjour,

Je réactive le post à la lecture de critiques sur PDO.

Pourtant, sur ce post, cela semble aller dans le bon sens et reprend d'ailleurs les recommandations de moogli :D. Mais le post que je cite, date de 2009, peut-être que ça a changé depuis :
I prefer PDO for the single reason that it allows named parameters for prepared statements, and as far as I am aware mysqli does not.
Pour l'insertion en base tu peux utiliser PDO, et une (ou plusieurs) requête(s) préparée(s).
J'ai cherché sur l'internet un tableau comparatif, je suis tombé sur celui-ci, mais à vrai dire... #-o c'est un peu abstrait à mon niveau de compréhension !
Serait-il possible d'avoir les avantages majeurs et idem pour les inconvénients de PDO et de mysqli par exemple ? Parce que je vais commencer à retrousser mes manches, mais j'aimerais autant ne pas avoir à changer de langage à alors que c'est déjà un exploit que je m'aventure jusque là :mrgreen:

D'avance, grand merci :)

McCallum

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

17 nov. 2015, 18:02

salut,

il n'y a pas d'avantage majeurs à l'un ou l'autre.
La différence majeur c'est mysqli ets liée à mysql alors que PDO non (équivalent du jdbc java si tu connais).

Donc avec PDO tu peux potentiellement changer de type de base de donnée sans toucher au code.
Dans la pratique étant donné que personne n'est capable / ne veux respecter les normes SQL tu finiras toujours par pondre du code spécifique au SGBD cible donc l'argument n'est valable que si tu penses que tu vas changer à un moment ou un autre. (perso il m'arrive de commencer par tester avec mysqli puis de m'orienter ensuite vers un autre sgbd).

L'argument des marqueurs nommés est bon pour la lisibilité du code, en dehors de cela aucun intérêt. Mais la lisibilité du code est primordiale pour une maintenance simple est rapide (insert into latable values(:nom,:prenom, :motdepasse) c'est quand même plus facile à lire que insert into latable values(?,?,?) ).

Perso j'ai fait une application qui peu avoir en cible mysql ou oracle, ou postgre sql ou sqlite (et déclinable pour tout driver de PDO) il m'a fallu gérer des requêtes spécifique SGBD mais toujours avec PDO et une seule connexion définie dans le fichier de conf.

Après si l'on descends au niveau du code je préfère le fetch de PDO (qui est configurable dès la connexion et pas besoin de chercher si on fetch_row, assoc, array, object, all...).
Cela reste surtout un ressentis, si tu te sens à l'aise avec PDO garde, si c'est mysqli et que tu n'utiliseras que mysql c'est bien aussi.

Dernière aspect important : la POO. si tu code en procédurale (quelques que soient tes raisons tu as le droit ça fonctionne très bien) tu peux le faire avec mysqli sans trop de modification depuis mysql et passer en douceur.
Si tu veux passer à la POO tu peux commencer a familiariser à la syntaxe d'utilisation avec PDO même s'il serait préférable de commencer par un court.

Bref tous ça pour te dire que tu as deux outils équivalents et que dans ce cas c'est toujours celaui avec lequel on se sens le mieux que l'on va bosser.
Pas la peine de d'imposer un truc si c'est pas utile au final.
et dans les deux cas ne prends les requêtes préparées comme arguments utiliser l'un ou l'autre car tous les deux ne font pas de "vrai" requêtes préparées sur le serveur (en pdo c'est configurable). Les personnes qui avance cet argument c'est pour éviter de rabâcher aux gens de "protéger" les données que l'on manipule dans les requêtes et que, dans certaines mesures, les requêtes préparées le fond pour toi.

voila test, amuse toi et quand tu te sens bien avec l'un ou l'autre fait ton choix :)

ah dernière chose, l'argument performance est justifiable si ton application à réellement beaucoup, beaucoup de requêtes c'est pas avec 5000 visites par jours qu'il faut s’inquiéter :) (en fait beaucoup d'application n'ont pas a ce soucier de cela la charge étant simplement absorbée tranquillement par les machines ;) ).

@+
Il en faut peu pour être heureux ......