OVH Cloud OVH Cloud

JDOM et validation DTD

8 réponses
Avatar
figus
Bonjour à tous

Je bosse avec le JDK 1.4.2 et JDOM 1.0.

Je souhaite charger et valider des fichiers XML ayant un DOCTYPE du genre
: <!DOCTYPE plugin SYSTEM "$CHEMIN/dtd/plugin.dtd">

Mon problème est lié à $CHEMIN.
Quand je crée mon DOM, j'ai une erreur de chargement de la DTD.

J'ai partiellement résolu mon problème en forçant le non-chargement de
la DTD externe :

SAXBuilder parser = new SAXBuilder("org.apache.xerces.parsers.SAXParser");
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

Ca me permet de voir si le XML est bien formé, mais pas s'il valide la
DTD bien sur.

Je pourrais ensuite facilement changer le DocType en instantiant
$CHEMIN et valider.

Mais, je n'ai pas l'impression que ce soit possible. J'ai bien lu la doc
de JDOM et il est bien dit que JDOM ne permet pas de garantir un DOM
valide par rapport à une DTD. Et je n'ai rien vu dans les API du JDK non plus.

Auriez-vous déjà rencontré ce problème ?
Comment l'avez-vous résolu ?

J'ai bien une idée, mais si y'a mieux je suis preneur. Ma solution serait
de générer un fichier temporaire (avec le doctype instantié et
accessible) et de le recharger en DOM. La validation pouvant avoir lieu.

Merci d'avance à tous.

8 réponses

Avatar
ludo06
figus wrote:
Bonjour à tous

Je bosse avec le JDK 1.4.2 et JDOM 1.0.

Je souhaite charger et valider des fichiers XML ayant un DOCTYPE du genre
: <!DOCTYPE plugin SYSTEM "$CHEMIN/dtd/plugin.dtd">

Mon problème est lié à $CHEMIN.
Quand je crée mon DOM, j'ai une erreur de chargement de la DTD.

J'ai partiellement résolu mon problème en forçant le non-chargement de
la DTD externe :

SAXBuilder parser = new SAXBuilder("org.apache.xerces.parsers.SAXParser");
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

Ca me permet de voir si le XML est bien formé, mais pas s'il valide la
DTD bien sur.

Je pourrais ensuite facilement changer le DocType en instantiant
$CHEMIN et valider.

Mais, je n'ai pas l'impression que ce soit possible. J'ai bien lu la doc
de JDOM et il est bien dit que JDOM ne permet pas de garantir un DOM
valide par rapport à une DTD. Et je n'ai rien vu dans les API du JDK non plus.

Auriez-vous déjà rencontré ce problème ?
Comment l'avez-vous résolu ?

J'ai bien une idée, mais si y'a mieux je suis preneur. Ma solution serait
de générer un fichier temporaire (avec le doctype instantié et
accessible) et de le recharger en DOM. La validation pouvant avoir lieu.

Merci d'avance à tous.


En general on utilise un EntityResolver qui est appele pour resoudre les

entites rencontrees lors de la lecture du xml. Il y a des
implementations apache d'entity resolver par exemple (xml-commons,
implementation des catalogues oasis) et tu peux configurer tes lecteurs
de xml pour qu'ils les utilisent (en SAx, DOM). Je ne sais pas si JDOM
peut utiliser des entity resolver mais comme ils utilise de maniere osus
jacente les autres APIs tu pouvoir utiliser un entity resolver avec.

Fais une recherche sur google a propos d'entity resolver et des
catlogues oasis si tu veux en savoir plus.

--
Cordialement,
---
Ludo
----
http://www.ubik-products.com

Avatar
ludo06
figus wrote:
Bonjour à tous

Je bosse avec le JDK 1.4.2 et JDOM 1.0.

Je souhaite charger et valider des fichiers XML ayant un DOCTYPE du genre
: <!DOCTYPE plugin SYSTEM "$CHEMIN/dtd/plugin.dtd">

Mon problème est lié à $CHEMIN.
Quand je crée mon DOM, j'ai une erreur de chargement de la DTD.

J'ai partiellement résolu mon problème en forçant le non-chargement de
la DTD externe :

SAXBuilder parser = new SAXBuilder("org.apache.xerces.parsers.SAXParser");
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

Ca me permet de voir si le XML est bien formé, mais pas s'il valide la
DTD bien sur.

Je pourrais ensuite facilement changer le DocType en instantiant
$CHEMIN et valider.

Mais, je n'ai pas l'impression que ce soit possible. J'ai bien lu la doc
de JDOM et il est bien dit que JDOM ne permet pas de garantir un DOM
valide par rapport à une DTD. Et je n'ai rien vu dans les API du JDK non plus.

Auriez-vous déjà rencontré ce problème ?
Comment l'avez-vous résolu ?

J'ai bien une idée, mais si y'a mieux je suis preneur. Ma solution serait
de générer un fichier temporaire (avec le doctype instantié et
accessible) et de le recharger en DOM. La validation pouvant avoir lieu.

Merci d'avance à tous.


En general on utilise un EntityResolver qui est appele pour resoudre les

entites rencontrees lors de la lecture du xml.

Il y a des implementations apache d'entity resolver par exemple
(xml-commons, implementation des catalogues oasis) et tu peux configurer
tes lecteurs de xml pour qu'ils les utilisent (en SAX, DOM).

Je ne sais pas si JDOM peut utiliser des entity resolver mais comme ils
utilise de maniere sous jacente les autres APIs tu dois pouvoir utiliser
un entity resolver avec.

Fais une recherche sur google a propos d'entity resolver et des
catlogues oasis si tu veux en savoir plus.

--
Cordialement,
---
Ludo
----
http://www.ubik-products.com

Avatar
ludo06
ludo06 wrote:
figus wrote:

Bonjour à tous

Je bosse avec le JDK 1.4.2 et JDOM 1.0.

Je souhaite charger et valider des fichiers XML ayant un DOCTYPE du genre
: <!DOCTYPE plugin SYSTEM "$CHEMIN/dtd/plugin.dtd">

Mon problème est lié à $CHEMIN.
Quand je crée mon DOM, j'ai une erreur de chargement de la DTD.

J'ai partiellement résolu mon problème en forçant le non-chargement de
la DTD externe :

SAXBuilder parser = new
SAXBuilder("org.apache.xerces.parsers.SAXParser");
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);

Ca me permet de voir si le XML est bien formé, mais pas s'il valide la
DTD bien sur.

Je pourrais ensuite facilement changer le DocType en instantiant
$CHEMIN et valider.

Mais, je n'ai pas l'impression que ce soit possible. J'ai bien lu la doc
de JDOM et il est bien dit que JDOM ne permet pas de garantir un DOM
valide par rapport à une DTD. Et je n'ai rien vu dans les API du JDK
non plus.

Auriez-vous déjà rencontré ce problème ?
Comment l'avez-vous résolu ?

J'ai bien une idée, mais si y'a mieux je suis preneur. Ma solution serait
de générer un fichier temporaire (avec le doctype instantié et
accessible) et de le recharger en DOM. La validation pouvant avoir lieu.

Merci d'avance à tous.


En general on utilise un EntityResolver qui est appele pour resoudre les

entites rencontrees lors de la lecture du xml.

Il y a des implementations apache d'entity resolver par exemple
(xml-commons, implementation des catalogues oasis) et tu peux configurer
tes lecteurs de xml pour qu'ils les utilisent (en SAX, DOM).

Je ne sais pas si JDOM peut utiliser des entity resolver mais comme ils
utilise de maniere sous jacente les autres APIs tu dois pouvoir utiliser
un entity resolver avec.

Fais une recherche sur google a propos d'entity resolver et des
catlogues oasis si tu veux en savoir plus.

A la reflexion je ne suis pas sur d'avoir bien saisi ce que tu veux

faire et donc ma reponse doit etre a cote de la plaque...
--
Cordialement,
---
Ludo
----
http://www.ubik-products.com


Avatar
SL

Bonjour à tous

Je bosse avec le JDK 1.4.2 et JDOM 1.0.

Je souhaite charger et valider des fichiers XML ayant un DOCTYPE du genre
: <!DOCTYPE plugin SYSTEM "$CHEMIN/dtd/plugin.dtd">


Je ne suis pas sûr à 100%, mais il semble que le problème est que ce
document est tout simplement mal formé. Un identifieur ne peut pas
contenir une variable d'environnement comme "$CHEMIN" : ce n'est pas une
uri valide.

Partant de là, la meilleure solution serait, si c'est possible, d'avoir
des documents bien formés...

Ca me permet de voir si le XML est bien formé, mais pas s'il valide la
DTD bien sur.


Je pense (sans être sûr) que Le document n'est *pas* bien formé, s'il
contient une uri incorrecte après le mot clef "SYSTEM".

J'ai bien une idée, mais si y'a mieux je suis preneur. Ma solution serait
de générer un fichier temporaire (avec le doctype instantié et
accessible) et de le recharger en DOM. La validation pouvant avoir lieu.


Cette solution consiste finalement à générer un document XML bien formé ;
pourquoi ne pas faire cette modification avec n'importe quel langage de
script ou en java (inutile de faire l'analyse syntaxique du XML - que ce
document n'est d'ailleurs pas), pour ensuite le parser normalement ?

slv

Avatar
figus
ludo06 wrote:
[je coupe la description de mon problème]
ludo06 wrote:
[je coupe la proposition d'utilisation d'un Entity Resolver]

A la reflexion je ne suis pas sur d'avoir bien saisi ce que tu veux
faire et donc ma reponse doit etre a cote de la plaque...


Je crois que c'est une bonne piste. Je n'ai pas encore tout compris par
rapport à la mise en oeuvre, mais ça semble pouvoir solutionner mon
souci de manière élégante.

D'après ce que je comprends, il suffirait que je définisse mon propore
Entity Resolver pour résoudre mes DocType non accessibles avec des
DocType accessibles.

Comme ça, au moment du build du DOM, ça roule. Il ne me reste plus qu'à
essayer et voir ce que ça donne.

Merci pour ta réponse.

Avatar
figus
SL wrote:
Je souhaite charger et valider des fichiers XML ayant un DOCTYPE du genre
: <!DOCTYPE plugin SYSTEM "$CHEMIN/dtd/plugin.dtd">


Je ne suis pas sûr à 100%, mais il semble que le problème est que ce
document est tout simplement mal formé. Un identifieur ne peut pas
contenir une variable d'environnement comme "$CHEMIN" : ce n'est pas
une uri valide.

Partant de là, la meilleure solution serait, si c'est possible, d'avoir
des documents bien formés...


Je ne saurai dire si ça relève de la malformation ou pas, mais l'erreur
qui m'est remonté mentionne plutôt une entité non résolue.

Ca me permet de voir si le XML est bien formé, mais pas s'il valide la
DTD bien sur.


Je pense (sans être sûr) que Le document n'est *pas* bien formé, s'il
contient une uri incorrecte après le mot clef "SYSTEM".


Je ne me suis pas intéressé du tout à avoir une URI correcte ou pas en
fait. Ceci étant dit, est-ce que ceci
<!DOCTYPE plugin PUBLIC "http://monsite.com/mesdtd/plugin.dtd">
et ceci
<!DOCTYPE plugin SYSTEM "dtd/plugin.dtd">
seraient corrects ?

J'ai bien une idée, mais si y'a mieux je suis preneur. Ma solution serait
de générer un fichier temporaire (avec le doctype instantié et
accessible) et de le recharger en DOM. La validation pouvant avoir lieu.


Cette solution consiste finalement à générer un document XML bien formé
; pourquoi ne pas faire cette modification avec n'importe quel langage
de script ou en java (inutile de faire l'analyse syntaxique du XML -
que ce document n'est d'ailleurs pas), pour ensuite le parser
normalement ?


Je suis sur la piste de mon propre Entity Resolver (comme suggéré par
ludo06) qui substituerait un DocType accessible. Comme ça prend place
avant le build du DOM, c'est tout à fait adéquat.


Avatar
SL

Ca me permet de voir si le XML est bien formé, mais pas s'il valide la
DTD bien sur.
Je pense (sans être sûr) que Le document n'est *pas* bien formé, s'il

contient une uri incorrecte après le mot clef "SYSTEM".


Je ne me suis pas intéressé du tout à avoir une URI correcte ou pas en
fait.


Si c'est vous qui générez le document, le plus simple est d'avoir une uri
correcte pour pouvoir valider le document dans la foulée !

Ceci étant dit, est-ce que ceci
<!DOCTYPE plugin PUBLIC "http://monsite.com/mesdtd/plugin.dtd">
et ceci
<!DOCTYPE plugin SYSTEM "dtd/plugin.dtd">
seraient corrects ?


Oui, il faut des uri classique, absolues ou relatives. Les variables
d'environnement ne peuvent pas être gérées dans le contexte XML, il faut
résoudre ces variables avant d'entrer dans le parseur. Une solution
d'indirection, si nécessaire, est de gérer les uri de façon centralisée
dans un catalogue ; mais cela n'autorise pas non plus l'utilisation de
variable d'environnement.

J'ai bien une idée, mais si y'a mieux je suis preneur. Ma solution
serait
de générer un fichier temporaire (avec le doctype instantié et
accessible) et de le recharger en DOM. La validation pouvant avoir
lieu.
Cette solution consiste finalement à générer un document XML bien

formé ; pourquoi ne pas faire cette modification avec n'importe quel
langage de script ou en java (inutile de faire l'analyse syntaxique du
XML - que ce document n'est d'ailleurs pas), pour ensuite le parser
normalement ?


Je suis sur la piste de mon propre Entity Resolver (comme suggéré par
ludo06) qui substituerait un DocType accessible. Comme ça prend place
avant le build du DOM, c'est tout à fait adéquat.


Dans tous les cas le plus sain, à mon avis, reste toujours de ne générer
que des documents bien formé... S'il faut utiliser un niveau
d'indirection, pourquoi ne pas utiliser des mots clefs "PUBLIC" :

<!DOCTYPE plugin PUBLIC "-// my dtd">

et mapper ces identifiants publics avec des uri dans un catalog,
éventuellement géré, depuis EntityResolver, par com.arbortext.Catalog de
Norman Walsh (http://www.arbortext.com/catalog.html). Ca serait XMLment
orthodoxe, sans hackage d'uri.

slv



Avatar
SL
Je suis sur la piste de mon propre Entity Resolver (comme suggéré par
ludo06) qui substituerait un DocType accessible. Comme ça prend place
avant le build du DOM, c'est tout à fait adéquat.


Dans tous les cas le plus sain, à mon avis, reste toujours de ne générer
que des documents bien formé... S'il faut utiliser un niveau
d'indirection, pourquoi ne pas utiliser des mots clefs "PUBLIC" :

<!DOCTYPE plugin PUBLIC "-// my dtd">

et mapper ces identifiants publics avec des uri dans un catalog,
éventuellement géré, depuis EntityResolver, par com.arbortext.Catalog de
Norman Walsh (http://www.arbortext.com/catalog.html). Ca serait XMLment
orthodoxe, sans hackage d'uri.



Plus simple, comme le dit ludo06 : le CatalogResolver de Apache
(http://xml.apache.org/commons/components/apidocs/resolver/index.html) qui
vous épargne l'écriture de votre propre implementation d'un
EntityResolver. Ce Resolver utilise un document "catalog" pour résoudre
les uri. Il faut donc écrire ce document : cf. un exemple dans un article
d'Apache :
http://xml.apache.org/commons/components/resolver/resolver-article.html.
Par contre, pour être rigoureux, il vaut mieux utiliser le mot clef
"PUBLIC" avec un identifiant public, qui dit bien ce qu'il est, qu'un mot
clef "SYSTEM" avec une uri qui n'en est pas une, même si elle est
interceptée et remplacée par une bonne uri dans le catalogue.