XML To Java avec JAXB (Unmarshaller)

Fermé
JeuneCodeur - 7 avril 2021 à 11:20
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 - 7 avril 2021 à 17:43
Bonjour,

J'ai un XML sous ce format la, et je n'arrive pas à récupérer les informations pour les transformer en objet.



<TEST>
  <NOM test1="a" test2="b" test3="c" test3="d">
   <NOM2 test10="aa" test20="bb" test30="cc"/>
   <NOM3 test100="aaa" test200="bbb" test300="ccc">
        <NOM4 test1000="aaaa" test2000="bbbb" test3000="cccc"/>
   </NOM3>
  </NOM4>
</TEST>


 public static void main(String[] args) 
    {
        String fileName = "test.xml";
 
        jaxbXmlFileToObject(fileName);
    }
 
    private static void jaxbXmlFileToObject(String fileName) {
 
        File xmlFile = new File(fileName);
 
        JAXBContext jaxbContext;
        try
        {
            jaxbContext = JAXBContext.newInstance(Student.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
 
            Student employee = (Student) jaxbUnmarshaller.unmarshal(xmlFile);
 
            System.out.println(employee);
        }
        catch (JAXBException e) 
        {
            e.printStackTrace();
        }
    }


J'aimerais crée un objet pour chaque NOM1 ( car sur mon XML d'origine j'en ai bcp plus) et récupérer les informations tq que test10 test200 par exemple.

Merci d'avance
A voir également:

2 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
7 avril 2021 à 13:49
Bonjour,

Tout d'abord ton fichier XML est faux. :
  • En ligne 2 tu ne peux pas avoir deux fois le même champs test3
  • En ligne 7 tu devrais avoir </NOM> au lieu de </NOM4>


Ensuite, quelle est la structure de ta classe Student ? Car JAXB va se baser là dessus pour parser ton fichier.
0
Bonjour,

Oui effectivement, c'est une erreur d'inattention.

Car j'ai pas voulu mettre mon fichier avec 1000000 de lignes, j'ai fait une version plus courte.

Du coup comment je peux le transformer en objet ?
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
7 avril 2021 à 17:43
Tout d'abord il te faut un XSD, c'est le contrat de ton XML.
Il existe des outils en lignes dans lequel tu peux mettre un code XML (le plus complet possible) et ça te génère le XSD correspondant => https://www.google.fr/search?q=xml+to+xsd

Ensuite, il te faut une ancienne version de Java (car JAXB n'est plus dans les versions récentes).
Par exemple en Java 8, en mettant le XSD dans un fichier E:\jaxb\test.xsd
cd E:\jaxb
"C:\Program Files\Java\jdk1.8.0_241\bin\xjc.exe" test.xsd

Cela va te générer des classes Java au format JAXB, dans le répertoire courant (E:\jaxb pour moi)

test.xml
<TEST>
  <NOM test1="a" test2="b" test3="c" test4="d">
   <NOM2 test10="aa" test20="bb" test30="cc"/>
   <NOM3 test100="aaa" test200="bbb" test300="ccc">
        <NOM4 test1000="aaaa" test2000="bbbb" test3000="cccc"/>
   </NOM3>
  </NOM>
</TEST>

test.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="TEST">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="NOM">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="NOM2">
                <xs:complexType>
                  <xs:attribute name="test10" type="xs:string" use="required" />
                  <xs:attribute name="test20" type="xs:string" use="required" />
                  <xs:attribute name="test30" type="xs:string" use="required" />
                </xs:complexType>
              </xs:element>
              <xs:element name="NOM3">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="NOM4">
                      <xs:complexType>
                        <xs:attribute name="test1000" type="xs:string" use="required" />
                        <xs:attribute name="test2000" type="xs:string" use="required" />
                        <xs:attribute name="test3000" type="xs:string" use="required" />
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="test100" type="xs:string" use="required" />
                  <xs:attribute name="test200" type="xs:string" use="required" />
                  <xs:attribute name="test300" type="xs:string" use="required" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="test1" type="xs:string" use="required" />
            <xs:attribute name="test2" type="xs:string" use="required" />
            <xs:attribute name="test3" type="xs:string" use="required" />
            <xs:attribute name="test4" type="xs:string" use="required" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

TEST.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "nom" })
@XmlRootElement(name = "TEST")
public class TEST {
    @XmlElement(name = "NOM", required = true)
    protected TEST.NOM nom;

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = { "nom2", "nom3" })
    public static class NOM {
        @XmlElement(name = "NOM2", required = true)
        protected TEST.NOM.NOM2 nom2;
        @XmlElement(name = "NOM3", required = true)
        protected TEST.NOM.NOM3 nom3;
        @XmlAttribute(name = "test1", required = true)
        protected String test1;
        @XmlAttribute(name = "test2", required = true)
        protected String test2;
        @XmlAttribute(name = "test3", required = true)
        protected String test3;
        @XmlAttribute(name = "test4", required = true)
        protected String test4;

        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "")
        public static class NOM2 {
            @XmlAttribute(name = "test10", required = true)
            protected String test10;
            @XmlAttribute(name = "test20", required = true)
            protected String test20;
            @XmlAttribute(name = "test30", required = true)
            protected String test30;
        }

        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "", propOrder = { "nom4" })
        public static class NOM3 {
            @XmlElement(name = "NOM4", required = true)
            protected TEST.NOM.NOM3 .NOM4 nom4;
            @XmlAttribute(name = "test100", required = true)
            protected String test100;
            @XmlAttribute(name = "test200", required = true)
            protected String test200;
            @XmlAttribute(name = "test300", required = true)
            protected String test300;

            @XmlAccessorType(XmlAccessType.FIELD)
            @XmlType(name = "")
            public static class NOM4 {
                @XmlAttribute(name = "test1000", required = true)
                protected String test1000;
                @XmlAttribute(name = "test2000", required = true)
                protected String test2000;
                @XmlAttribute(name = "test3000", required = true)
                protected String test3000;
            }
        }
    }
}

Remarque : normalement en XML les balises devraient être en minuscules, si tu respectes cette convention cela te permettra d'avoir un code Java qui respecte lui aussi les conventions d'écriture, alors que là on a des noms de classes tout en majuscule ce qui n'est pas standard...
0