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 valider un fichier schema (le XSD lui-même) [XSD]


Sujet :

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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de paissad
    Homme Profil pro
    Ingénieur de développement (Java/JEE/Eclipse RCP,EMF & webMethods)
    Inscrit en
    Avril 2006
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur de développement (Java/JEE/Eclipse RCP,EMF & webMethods)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 043
    Par défaut Comment valider un fichier schema (le XSD lui-même)
    Bonjour,
    je voudrais valider un fichier XSD pour vérifier qu'il a bien été formé.
    Dans ce fichier XSD, je n'ai, pour l'exemple et le test, utilisé que des balises par défaut et sans namespace.
    voici le fichier XSD que je veux valider.
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <?xml version='1.0' encoding='utf-8' ?>
    <schema xmlns='http://www.w3.org/2001/XMLSchema' elementFormDefault='qualified' version='1.0'>
      <annotation>
        <documentation>...</documentation>
      </annotation>    
    </schema>
    En cela, j'ai téléchargé les XSD et DTD se trouvant ici http://www.w3.org/2001/XMLSchema et j'utilise donc le fichier XMLSchema .xsd pour ma validation.
    Mais lorsque je lance la validation, j'ai l'erreur suivante:
    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
    org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'xml:lang' to a(n) 'attribute declaration' component.
    	at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    	at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
    	at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    	at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDHandler.reportSchemaError(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDHandler.getGlobalDecl(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDAttributeTraverser.traverseLocal(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDAbstractTraverser.traverseAttrsAndAttrGrps(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDComplexTypeTraverser.processComplexContent(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDComplexTypeTraverser.traverseComplexContent(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDComplexTypeTraverser.traverseComplexTypeDecl(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDComplexTypeTraverser.traverseLocal(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDElementTraverser.traverseNamedElement(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDElementTraverser.traverseGlobal(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDHandler.traverseSchemas(Unknown Source)
    	at org.apache.xerces.impl.xs.traversers.XSDHandler.parseSchema(Unknown Source)
    	at org.apache.xerces.impl.xs.XMLSchemaLoader.loadSchema(Unknown Source)
    	at org.apache.xerces.impl.xs.XMLSchemaLoader.loadGrammar(Unknown Source)
    	at org.apache.xerces.impl.xs.XMLSchemaLoader.loadGrammar(Unknown Source)
    	at org.apache.xerces.jaxp.validation.XMLSchemaFactory.newSchema(Unknown Source)
    	at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:594)
    	at xx.yyy.zzzzzz.util.XMLUtils.validate(XMLUtils.java:226)
    	at xx.yyy.zzzzzz.config.ConfigurationValidator.validateOneFragmentFile(ConfigurationValidator.java:303)
    	at xx.yyy.zzzzzz.config.ConfigurationValidator.generateProcessXSD(ConfigurationValidator.java:123)
    	at xx.yyy.zzzzzz.runner.SoftwareRunner.generateProcessXSDIfSpecifiedAndExit(SoftwareRunner.java:238)
    	at xx.yyy.zzzzzz.runner.SoftwareRunner.main(SoftwareRunner.java:142)
    Voici le code Java que j'utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
            final Source xsdSource = new SAXSource(new InputSource(xsdStream));
            final Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(xsdSource);
            final Validator validator = schema.newValidator();       
            final Source source = new StreamSource(xmlFile);
            try {
                validator.validate(source);
                return true;
            } catch (SAXException e) {
                return false;
            }
    L'exception est lancée au niveau du validator.validate(source);Je suis sous oracle JDK 6
    J'arrive très bien à valider des fichiers XML contre des XSD.
    J'obtiens cette exception uniquement lorsque j'essaie de valider un fichier XSD (qui n'est rien d'autre qu'un fichier XML aussi ...)
    J'ai un peu cherché déjà, mais je sèche.
    J'ai aussi téléchargé et mis dans mon CLASSPATH les lib xercesImpl et ses dépendances pour solutionner tout ceci, mais rien n'y fait.
    Est ce que quelqu'un d'autre aurait une solution ?
    Merci d'avance.
    Cordialement,
    Nous n'héritons pas de la terre de nos parents, nous l'empruntons à nos enfants.
    Le chat du site est aussi ici pour aider. Ne pas hésiter à visiter !

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    C'est probablement à cause de l'attribut xml:lang
    Le .xsd de XML Schema dit que l'élément <schema> peut avoir un attribut xml:lang.

    Par conséquent, quand le validateur cherche à valider l'élément <schema>, il a besoin de connaître la définition XML Schema de cet attribut xml:lang.

    Or, étant dans un namespace différent, il est défini dans un .xsd différent. On le trouve sur la page de définition du namespace "xml:".

    On peut supposer que ton SchemaFactory n'est pas configuré pour aller chercher ce .xsd sur Internet (ou que tu n'as pas accès à Internet, ou qu'il est souvent down.)

    Si c'est le cas, il faudrait que tu télécharges le .xsd en question et le mette à côté du .xsd de XML Schema. Puis, pour que ton appli sache où le trouver, tu auras besoin de SchemaFactory.setResourceResolver(), qui indiquera donc où trouver ce .xsd-là dans ton application.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Modérateur
    Avatar de paissad
    Homme Profil pro
    Ingénieur de développement (Java/JEE/Eclipse RCP,EMF & webMethods)
    Inscrit en
    Avril 2006
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur de développement (Java/JEE/Eclipse RCP,EMF & webMethods)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 043
    Par défaut
    Merci thelvin.
    J'ai bien cherché le XSD qui pourrait contenir cette définition, mais après une longue recherche, je ne trouve pas du tout, donc je ne pourrais pas l'inclure comme j'ai pu le faire pour 'Schema.xsd', 'Schema.dtd' et 'datatypes.dtd'
    Je comprends bien le principe de EntityResolver, mais faudrait bien à un moment que je puisse avoir le XSD :/
    Par ailleurs, l'application ne doit surtout pas aller sur internet, donc tant mieux si ça bloque à cause d'une connexion bloquée à internet.
    Alors peut être que j'ai mal compris ce que tu m'expliquais :/
    Nous n'héritons pas de la terre de nos parents, nous l'empruntons à nos enfants.
    Le chat du site est aussi ici pour aider. Ne pas hésiter à visiter !

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par paissad Voir le message
    J'ai bien cherché le XSD qui pourrait contenir cette définition, mais après une longue recherche, je ne trouve pas du tout
    Pourtant je n'ai pas eu de mal à le trouver, le schéma pour le namespace xml:. Il est sur la page que je t'avais pointée, dans la liste des ressources, sur le mot "fragment."

    Citation Envoyé par paissad Voir le message
    Je comprends bien le principe de EntityResolver, mais faudrait bien à un moment que je puisse avoir le XSD :/
    Attention, c'est le même principe qu'un EntityResolver, mais c'en est pas un. Me demande pas pourquoi, personnellement je trouve pas ça finaud.

    Citation Envoyé par paissad Voir le message
    Par ailleurs, l'application ne doit surtout pas aller sur internet, donc tant mieux si ça bloque à cause d'une connexion bloquée à internet.
    Alors peut être que j'ai mal compris ce que tu m'expliquais :/
    Si c'est voulu, très bien, moi je ne pouvais pas le savoir, j'envisageais des causes possibles.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Modérateur
    Avatar de paissad
    Homme Profil pro
    Ingénieur de développement (Java/JEE/Eclipse RCP,EMF & webMethods)
    Inscrit en
    Avril 2006
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur de développement (Java/JEE/Eclipse RCP,EMF & webMethods)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 043
    Par défaut Solution et code "final".
    Rebonjour,
    Bon, j'ai finalement trouvé la solution en suivant les indications que tu m'as données.
    Je "résume".
    J'ai fait une implémentation de LSResourceResolver
    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
     
    private static class CustomLSResourceResolver implements LSResourceResolver {
     
            CustomLSResourceResolver() {
            }
     
            @Override
            public LSInput resolveResource(
                    String type, String namespaceURI, String publicId, String systemId, String baseURI) {
                InputStream input = null;
                if (systemId.equals("http://www.w3.org/2001/xml.xsd")) {
                    input = Thread.currentThread().getClass().getResourceAsStream("/xsd/xml.xsd");
                }
                return new CustomLSInput(systemId, publicId, baseURI, input);
            }
        }
    CustomLSInput est une implémentation de LSInput

    Voici mon implémentation de LSInput
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    private static class CustomLSInput implements LSInput {
     
            private String      systemId;
            private String      publicId;
            private String      baseURI;
            private InputStream input;
     
            CustomLSInput(String systemId, String publicId, String baseURI, InputStream input) {
                this.systemId = systemId;
                this.publicId = publicId;
                this.baseURI = baseURI;
                this.input = input;
            }
     
            @Override
            public Reader getCharacterStream() {
                return null;
            }
     
            @Override
            public void setCharacterStream(Reader characterStream) {
            }
     
            @Override
            public InputStream getByteStream() {
                return null;
            }
     
            @Override
            public void setByteStream(InputStream byteStream) {
            }
     
            @Override
            public String getStringData() {
                if (this.input == null) return null;
                try {
                    byte[] data = new byte[this.input.available()];
                    this.input.read(data);
                    final String contents = new String(data);
                    return contents;
                } catch (IOException e) {
                    e.printStackTrace(System.err);
                    return null;
                }
            }
     
            @Override
            public void setStringData(String stringData) {
            }
     
            @Override
            public String getSystemId() {
                return this.systemId;
            }
     
            @Override
            public void setSystemId(String systemId) {
            }
     
            @Override
            public String getPublicId() {
                return this.publicId;
            }
     
            @Override
            public void setPublicId(String publicId) {
            }
     
            @Override
            public String getBaseURI() {
                return this.baseURI;
            }
     
            @Override
            public void setBaseURI(String baseURI) {
            }
     
            @Override
            public String getEncoding() {
                return null;
            }
     
            @Override
            public void setEncoding(String encoding) {
            }
     
            @Override
            public boolean getCertifiedText() {
                return false;
            }
     
            @Override
            public void setCertifiedText(boolean certifiedText) {
            }
        }
    Mais cela ne suffit pas, il faut ensuite faire une implémentation de EntityResolver afin de pouvoir trouver la localisation des ressources "Schema.dtd" , "datatypes.dtd" etc ... (c'est obligatoire, sinon, si on veut se passer d'un EntityResolver, il faudrait poser ces fichier au même endroit où l'application a été lancé, c'est à dire à System.getProperty("user.dir");

    Voici mon implémentation d'EntityResolver.
    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
     
    private static class CustomXSDEntityResolver implements EntityResolver {
     
            CustomXSDEntityResolver() {
            }
     
            @Override
            public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
                InputStream xsd = null;
                if (systemId.equals(XMLConstants.XML_NS_URI)) {
                    xsd = CommonUtils.getResourceAsStream("/xsd/xml.xsd", false);
                } else if (systemId.endsWith("XMLSchema.dtd")) {
                    xsd = CommonUtils.getResourceAsStream("/xsd/XMLSchema.dtd", false);
                } else if (systemId.endsWith("datatypes.dtd")) {
                    xsd = CommonUtils.getResourceAsStream("/xsd/datatypes.dtd", false);
                } else {
                    // On laisse le comportement par défaut.
                    return null;
                }
                return new InputSource(xsd);
            }
        }
    Ensuite, je suis passé à la validation de mes fichiers XSD en passant, bien évidemment comme XSD -> Schema.xsd
    Je reposte le code simplifié de validation:
    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
     
            final InputStream xsdStream = Thread.currentThread().getClass().getResourceAsStream("/xsd/Schema.xsd");
             // Il faut quand même vérifier que xsdStream n'est pas null ...
            final XMLReader xmlReader = XMLReaderFactory.createXMLReader();
            xmlReader.setEntityResolver(new CustomXSDEntityResolver());
            final Source xsdSource = new SAXSource(xmlReader, new InputSource(xsd));
            final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            schemaFactory.setResourceResolver(new CustomLSResourceResolver());
            final Schema schema = schemaFactory.newSchema(xsdSource);
            final Validator validator = schema.newValidator();      
            final Source source = new StreamSource(xml);
            try {
                validator.validate(source);
                return true;
            } catch (SAXException e) {
                return false;
            }
    NOTE: Dans mon exemple de code, les fichiers "Schema.xsd", Schema.dtd, datatypes.dtd et xml.xsd se trouvent dans le répertoire src/main/resources/xsd (donc, dans le CLASSPATH pour plus de facilités)

    Merci pour tout.
    Nous n'héritons pas de la terre de nos parents, nous l'empruntons à nos enfants.
    Le chat du site est aussi ici pour aider. Ne pas hésiter à visiter !

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

Discussions similaires

  1. [Contributions] Comment valider un XML avec un XSD ?
    Par Community Management dans le forum Valider
    Réponses: 16
    Dernier message: 26/08/2015, 15h56
  2. [Web Service] comment valider un fichier wsdl 1.0 ?
    Par Merfolk dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 06/10/2010, 21h37
  3. Réponses: 3
    Dernier message: 24/07/2009, 14h04
  4. [XSD] Valider un fichier XML via XSD
    Par laury33 dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 05/03/2007, 16h46
  5. [xml][Java] Comment valider un fichier XML?
    Par ederf dans le forum Valider
    Réponses: 1
    Dernier message: 06/03/2006, 15h51

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