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 :

Comment générer dynamiquement une classe Java à partir d'un XML


Sujet :

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

  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut Comment générer dynamiquement une classe Java à partir d'un XML
    Bonjour,

    Je dois créé un .jar qui lit un fichier XML pour en créer dynamiquement une(des) (sous)classe(s) Java, plus ou moins automatiquement. Par exemple, le XML suivant :
    Code XML : 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
    18
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ns2:Metadatas xmlns="urn:metadata.01.00">
        <Metadata>
            <DateDepot>2019-07-23</DateDepot>
            <Motif>Mon motif</Motif>
            <SousMotif>Courrier</SousMotif>
            <Rattachement>
                <Caisse>666</Caisse>
                <Regime>66</Regime>
            </Rattachement>
            <PieceJointe>
                <NomFichier>PieceJointe.pdf</NomFichier>
                <TypeFichier>application/pdf</TypeFichier>
                <TypePiece>Piece jointe</TypePiece>
                <Empreinte FonctionDeHachage="SHA-256">ys7ht8vtTXWtWSC8nD+e7NOFpe/cZVYln9r1vDu+Pz4=</Empreinte>
            </PieceJointe>
        </Metadata>
    </ns2:Metadatas>
    Devrait donner une classe semblable à celle-ci :
    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
    18
    19
    20
    21
    public class Metadata {
        public Date dateDepot;
        public String motif;
        public String sousMotif;
        public Rattachement rattachement;
        public List<PieceJointe> pieceJointe;
    }
    public class Rattachement {
        public String caisse;
        public String regime;
    }
    public class PieceJointe {
        public NomFichier nomFichier;
        public String typeFichier;
        public String typePiece;
        public Empreinte empreinte;
    }
    public class Empreinte {
        protected byte[] value;
        protected String fonctionDeHachage;
    }
    Cette classe Metadata étendra une super-classe et sera utilisée ensuite avec une autre application.

    J'ai vu que xjc (JAXB) permet de créer des .java mais je ne vois pas comment intégrer ça dans mon .jar.

    Les XML seront d'une quinzaine de formats. Une solution que j'ai envisagée est de créer des bibliothèques correspondant à chaque XML mais je ne sais pas comment choisir dynamiquement la bibliothèque.
    Christophe

    Pensez à mettre quand c'est le cas.

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    JAXB, avec l'aide de la commande XJC permets en effet de creer tes classes java a partir d'un fichier XSD (qui est créable si tu ne l'as pas avec certains outils, en se basant sur un XML bien fourni comme exemple, mais il vaut mieux utiliser le bon schema directement).

    Une fois tes classes java crée, il te suffit de les inclures dans ton projet.

    https://www.jmdoudoux.fr/java/dej/chap-jaxb.htm
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut java.lang.InternalError
    Mon code génrère désormais une "java.lang.InternalError" :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    Exception in thread "main" java.lang.InternalError
            at com.sun.xml.internal.bind.v2.model.annotation.RuntimeInlineAnnotationReader.getClassValue(RuntimeInlineAnnotationReader.java:140)
            at com.sun.xml.internal.bind.v2.model.annotation.RuntimeInlineAnnotationReader.getClassValue(RuntimeInlineAnnotationReader.java:54)
            at com.sun.xml.internal.bind.v2.model.impl.PropertyInfoImpl.isApplicable(PropertyInfoImpl.java:214)
            at com.sun.xml.internal.bind.v2.model.impl.PropertyInfoImpl.getApplicableAdapter(PropertyInfoImpl.java:225)
            at com.sun.xml.internal.bind.v2.model.impl.PropertyInfoImpl.<init>(PropertyInfoImpl.java:124)
            at com.sun.xml.internal.bind.v2.model.impl.ERPropertyInfoImpl.<init>(ERPropertyInfoImpl.java:54)
            at com.sun.xml.internal.bind.v2.model.impl.ElementPropertyInfoImpl.<init>(ElementPropertyInfoImpl.java:97)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeElementPropertyInfoImpl.<init>(RuntimeElementPropertyInfoImpl.java:60)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeClassInfoImpl.createElementProperty(RuntimeClassInfoImpl.java:166)
            at com.sun.xml.internal.bind.v2.model.impl.ClassInfoImpl.addProperty(ClassInfoImpl.java:869)
            at com.sun.xml.internal.bind.v2.model.impl.ClassInfoImpl.findFieldProperties(ClassInfoImpl.java:399)
            at com.sun.xml.internal.bind.v2.model.impl.ClassInfoImpl.getProperties(ClassInfoImpl.java:302)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeClassInfoImpl.getProperties(RuntimeClassInfoImpl.java:177)
            at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:244)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:101)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:82)
            at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:210)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:96)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:82)
            at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:316)
            at com.sun.xml.internal.bind.v2.model.impl.TypeRefImpl.calcRef(TypeRefImpl.java:93)
            at com.sun.xml.internal.bind.v2.model.impl.TypeRefImpl.getTarget(TypeRefImpl.java:70)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeTypeRefImpl.getTarget(RuntimeTypeRefImpl.java:59)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeTypeRefImpl.getTarget(RuntimeTypeRefImpl.java:52)
            at com.sun.xml.internal.bind.v2.model.impl.ElementPropertyInfoImpl$1.get(ElementPropertyInfoImpl.java:75)
            at com.sun.xml.internal.bind.v2.model.impl.ElementPropertyInfoImpl$1.get(ElementPropertyInfoImpl.java:73)
            at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:57)
            at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:256)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:101)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:82)
            at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:210)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:96)
            at com.sun.xml.internal.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:82)
            at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:316)
            at com.sun.xml.internal.bind.v2.model.impl.RegistryInfoImpl.<init>(RegistryInfoImpl.java:100)
            at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.addRegistry(ModelBuilder.java:358)
            at com.sun.xml.internal.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:328)
            at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:444)
            at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:291)
            at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1128)
            at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:159)
            at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:126)
            at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:207)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
            at java.lang.reflect.Method.invoke(Method.java:611)
            at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:139)
            at javax.xml.bind.ContextFinder.find(ContextFinder.java:301)
            at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:383)
            at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:348)
            at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:255)
            at fr.sae.InjectionSynchroneXML.creerMetadataSmut(InjectionSynchroneXML.java:174)
    La ligne 174 correspond à celle commençant par "JAXBContext jc " :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	private static MetadataAIU creerMetadataSmut(File fichierPdi) throws JAXBException {
    		JAXBContext jc = JAXBContext.newInstance("fr.sae.smut.metadatas.versement.generated");
    		Unmarshaller unmarshaller = jc.createUnmarshaller();
    		fr.sae.smut.metadatas.versement.generated.Metadata metadataAiu = (fr.sae.smut.metadatas.versement.generated.Metadata) unmarshaller.unmarshal(fichierPdi);
    Le package "fr.sae.smut.metadatas.versement.generated" contient les classes correspondant au fichier "fichierPdi" qui ressemble à l'exemple précédent. Il ne contient pas d'annotation (et n'en contiendra jamais). Est-ce la cause de l'erreur sur RuntimeInlineAnnotationReader.java ?
    Christophe

    Pensez à mettre quand c'est le cas.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    J'ai remplacé la chaine par la classe mais ça donne la même erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    private static MetadataAIU creerMetadataSmut(File fichierPdi) throws JAXBException {
    		JAXBContext jc = JAXBContext.newInstance(fr.sae.smut.metadatas.versement.generated.Metadata.class);
    		Unmarshaller unmarshaller = jc.createUnmarshaller();
    		fr.sae.smut.metadatas.versement.generated.Metadata metadataAiu = (fr.sae.smut.metadatas.versement.generated.Metadata) unmarshaller.unmarshal(fichierPdi);
    Edition : Correction du code qui ne correspondant pas à la réalité.
    Christophe

    Pensez à mettre quand c'est le cas.

  5. #5
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Je ne suis pas sure dutout, mais ce ne serait pas plutot une Class que tu dois passer ? A tout hasard essaye comme ceci, mais j'avoue ne pas être certains que cela soit la cause.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    JAXBContext jc = JAXBContext.newInstance(fr.sae.smut.metadatas.versement.generated.Metadata.class);
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    Il y avait une erreur dans le copier-coller. C'est effectivement un .class en paramètre (code corrigé).
    Christophe

    Pensez à mettre quand c'est le cas.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    Le code suivant donne la même erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    		JAXBContext jc = JAXBContext.newInstance("fr.sae.smut.metadatas.versement.generated", 
    				fr.sae.smut.metadatas.versement.generated.ObjectFactory.class.getClassLoader());
    Christophe

    Pensez à mettre quand c'est le cas.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    L'erreur peut-elle provenir des classes correspondant aux XML ? Extrait :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "Metadata", propOrder = {
        "dateEnvoi",
        "organisme",
        "individu",
        "document"
    })
    public class Metadata
        extends MetadataAIU
    {
     
        @XmlElement(name = "DateEnvoi", required = true, type = String.class)
        @XmlJavaTypeAdapter(DateNoTimezoneAdapter.class)
        @XmlSchemaType(name = "date")
        protected Date dateEnvoi;
        @XmlElement(name = "Organisme", required = true)
        protected Organisme organisme;
        @XmlElement(name = "Individu", required = true)
        protected Individu individu;
        @XmlElement(name = "Document", required = true)
        protected Document document;
     
        /**
         * Obtient la valeur de la propriete dateEnvoi.
         * 
         * @return
         *     possible object is
         *     {@link String }
         *     
         */
        public Date getDateEnvoi() {
            return dateEnvoi;
        }
    ...
    Christophe

    Pensez à mettre quand c'est le cas.

  9. #9
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2003
    Messages
    1 303
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 303
    Points : 1 380
    Points
    1 380
    Par défaut
    J'ai abandonné l'utilisation de JAXB et tout fait à la main.
    Christophe

    Pensez à mettre quand c'est le cas.

Discussions similaires

  1. Réponses: 2
    Dernier message: 03/09/2013, 23h07
  2. Appel d'une classe Java à partir de Perl
    Par hadler dans le forum Langage
    Réponses: 7
    Dernier message: 28/11/2011, 07h26
  3. [SAX] Initialisation d'une méthode java à partir d'un xml
    Par Arno83 dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 26/02/2008, 11h03
  4. comment modifier dynamiquement une classe
    Par Olivierinfo dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 30/10/2007, 17h18
  5. Générer une classe java à partir d'une autre
    Par hebmaster dans le forum Général Java
    Réponses: 5
    Dernier message: 29/05/2006, 16h09

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