IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Format d'échange (XML, JSON...) Java Discussion :

Parse un XML contenant une DTD n'existant pas [DOM]


Sujet :

Format d'échange (XML, JSON...) Java

  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Par défaut Parse un XML contenant une DTD n'existant pas
    Bonjour

    Pour un projet sur lequel je travail, je doit pouvoir effectuer les opérations suivantes :
    - Charger un modèle de fichier XML (c'est un fichier XML)
    - Effectuer quelques modifications
    - Pouvoir l'enregistrer à un endroit donné.

    Le problème que je rencontre vient du fait que mon application (sous Windows) manipule un fichier qui doit être utilisé sous LINUX, et dont la DTD doit être en chemin absolu. Cette DTD doit être absolument être présente dans le fichier générer, conformément à ce qui est présent dans le modèle XML. Je ne peux pas préjuger du contenu de ce modèle.

    Si j'effectue les opérations suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(false);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(file);
    le parser se plaint comme quoi il ne trouve pas la DTD (setValidating(false) n'a pas l'air de faire ce que je souhaite).

    Je peux obtenir un parsing correct en ajoutant ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    builder.setEntityResolver(new EntityResolver()
    {
        @Override
        public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
        {
            return new InputSource(new java.io.StringReader(""));
        }
    });
    avant le parse. Oui mais... je perd la DTD lors de la sauvegarde de mon document.

    Voyez vous une solution ?

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    1) a quoi ressemble le doc de départ
    2) à quoi ressemble le doc d'arrivée que t'obtiens
    3) que devrais-tu obtenir
    4) quel est ton code de chargement / modification / sauvegarde (on n'a que le chargement là)

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 577
    Par défaut
    Citation Envoyé par jfouche Voir le message
    le parser se plaint comme quoi il ne trouve pas la DTD (setValidating(false) n'a pas l'air de faire ce que je souhaite).
    Ça fait, littéralement, ce que ça dit que ça fait. Ça dit qu'il ne faut pas valider.
    Si tu dis à ton enfant de ne pas aller mettre le désordre au salon. Tu ne lui as rien dit sur le fait d'aller au salon : il y va, il y va pas, c'est son problème. En tout cas, qu'il y aille ou pas, il a ordre formel de ne pas le mettre en désordre.
    C'est pareil avec le parseur XML. Tu lui as dit de ne pas valider, à tes ordres, il ne validera pas. Quoi ? Ne pas aller lire la DTD ? Personne ne m'a parlé de ça.

    Explication : validation ou pas, la DTD pourrait contenir des définitions d'entités internes (ou externes, d'ailleurs). Il ne sait pas s'il y en a, mais s'il y en a il les lui faut. Donc il va les chercher. Ça n'a rien à voir avec la validation, qui est rappelons-le, la vérification que le document respecte une grammaire annoncée.
    Il me semble qu'on peut lui dire de ne pas chercher à aller voir la DTD, mais je ne sais plus comment. Ça a à voir avec http://apache.org/xml/features/nonvalidating/load-external-dtd, trouvable ici : http://xerces.apache.org/xerces-j/features.html


    Citation Envoyé par jfouche Voir le message
    Oui mais... je perd la DTD lors de la sauvegarde de mon document.
    Rien à voir avec EntityResolver. Il ne touche pas au DOCTYPE annoncé par le fichier. Le problème est ailleurs.
    Notamment, la bonne vieille technique de sérialiser le Document avec un Transformer, efface toujours le doctype. L'une des nombreuses raisons pour lesquelles j'utilise plutôt JDOM.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Je rajoute qu'une DTD c'est une forme basique d'inclusion de définitions dans un document xml. Le transformer peux très bien prendre le contenu de la DTD et l'inclure telle quelle dans le document final plutot que de mettre un lien vers un document DTD.

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Par défaut
    Thelvin, merci beaucoup pour les explications, c'est plus clair pour moi.

    Le problème est ailleurs.
    Notamment, la bonne vieille technique de sérialiser le Document avec un Transformer, efface toujours le doctype.
    Bah voila, c'est ce que je fais...

    L'une des nombreuses raisons pour lesquelles j'utilise plutôt JDOM.
    Par contre, j'essaie de limiter au max le nombre de COTS pour mon produit, et j'aurai préféré une solution qui n'utilise pas une bibliotheque externe. J'ai rajouté le doctype récupérée avec l'EntityResolver au transformer, mais ça ne me parait pas terrible comme solution. En plus, ça rajoute file: au chemin de la DTD, ce que je n'ai pas testé avec le soft linux.

    PS : Le lien fourni ne marche pas...

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    si vous voulez convertir le url en nom de fichier , faites un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new File(new URL(ligne).toURI())

  7. #7
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Par défaut
    Je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Source source = new DOMSource(this.doc);
    File file = new File(filename);
    Result result = new StreamResult(file);
    try
    {
    	Transformer xformer = TransformerFactory.newInstance().newTransformer();
    	if (this.systemDTD != null)
    	{
    		xformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, this.systemDTD);
    	}
    	xformer.transform(source, result);
    }
    catch (Exception e)
    {
    	e.printStackTrace();
    	return false;
    }
    Difficile de proposer une conversion...

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 577
    Par défaut
    Utilise plutôt doc.getDocType().getSystemId(), inutile de chercher midi à quatorze heures.
    Attention quand même, getDoctype() renvoie null pour les documents qui n'ont pas de doctype.

    Par contre, j'essaie de limiter au max le nombre de COTS pour mon produit, et j'aurai préféré une solution qui n'utilise pas une bibliotheque externe.
    En Java ??! Non, non, je ne juge pas, chacun ses petits masochismes...

    PS : Le lien fourni ne marche pas...
    Quoi, http://xerces.apache.org/xerces-j/features.html ?
    Il marche maintenant, le serveur devait être down.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Par défaut
    Par contre, j'essaie de limiter au max le nombre de COTS pour mon produit, et j'aurai préféré une solution qui n'utilise pas une bibliotheque externe.
    En Java ??! Non, non, je ne juge pas, chacun ses petits masochismes...
    C'est plutôt qu'on a du envoyer au client la liste des COTS utilisé sur notre produit. Changer cette liste maintenant a un coût. De plus, nous passons un peu de temps à faire une analyse juridique des COTS que nous utilisons, et ça aussi a un coût (financier et temps).
    D'où ma recherche d'une solution sans COTS aujourd'hui. Par contre, nous utilisons bien plusieurs COTS sur notre produit (je ne refais pas qqchose qui existe...). Certains open sources, et d'autres achetés (ex : JIDE, que je conseil pour le rapport qualité / suivi / coût).

    Citation Envoyé par thelvin Voir le message
    Utilise plutôt doc.getDocType().getSystemId(), inutile de chercher midi à quatorze heures.
    Ca cartonne, en mieux que ce que j'avais : cela ne préfixe pas par file:

  10. #10
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Il doit être magique votre chef de projet, si il sait avant le développement de quelles librairies vous allez avoir besoin

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XML] Parser une DTD?
    Par La Truffe dans le forum Format d'échange (XML, JSON...)
    Réponses: 6
    Dernier message: 03/04/2007, 11h28
  2. [DTD] Valider un fichier xml suivant une DTD
    Par Tail dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 26/06/2006, 11h23
  3. Réponses: 2
    Dernier message: 03/06/2005, 11h00
  4. [XML][DTD] Générer un XML avec une DTD ?
    Par elitost dans le forum Valider
    Réponses: 6
    Dernier message: 04/05/2005, 12h48
  5. XML conforme à une DTD
    Par ange bleu dans le forum Valider
    Réponses: 4
    Dernier message: 20/04/2004, 09h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo