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 :

[DOM] - Valider un org.w3c.dom.Document construit programmatiquement avec un XSD


Sujet :

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

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut [DOM] - Valider un org.w3c.dom.Document construit programmatiquement avec un XSD
    Bonjour la communauté Java,

    Voila le problème sur lequel je me tape la tête sur le clavier depuis plusieurs jour.
    D'un côté je créé un document XML de cet manière:
    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
     
        try {
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     
          factory.setNamespaceAware(true);
     
          Source schemaFile = new StreamSource(new File("data/toto.xsd"));
     
          SchemaFactory sfactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
     
          Schema schema = sfactory.newSchema(schemaFile);
     
          factory.setSchema(schema);
     
          factory.setValidating(true);
     
          DocumentBuilder builder = factory.newDocumentBuilder();
     
          outputDocument = builder.newDocument();
     
          outputRoot = outputDocument.createElement("Toto");
     
          String xmlnsUri = "http://www.w3.org/2000/xmlns/";
          String xsiUri   = "http://www.w3.org/2001/XMLSchema-instance";
     
          Attr xsi      = outputDocument.createAttributeNS(xmlnsUri, "xmlns:xsi"                    );
          Attr location = outputDocument.createAttributeNS(xsiUri  , "xsi:noNamespaceSchemaLocation");
     
          xsi     .setValue("http://www.w3.org/2001/XMLSchema-instance");
          location.setValue("toto.xsd");
     
          outputRoot.setAttributeNodeNS(xsi     );
          outputRoot.setAttributeNodeNS(location);
     
          outputDocument.appendChild(outputRoot);
        } catch (ParserConfigurationException e) {
          e.printStackTrace();
        } catch (SAXException e) {
          e.printStackTrace();
        }
    De l'autre je valide, après remplissage du DOM, avec ce bout de code:

    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
     
        try {
          SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
     
          Source schemaFile = new StreamSource(new File("data/toto.xsd"));
     
          Schema schema = factory.newSchema(schemaFile);
     
          Validator validator = schema.newValidator();
     
          // status.getOutputDocument() retourne outputDocument précédemment créé 
          validator.validate(new DOMSource(status.getOutputDocument()));
        } catch (SAXException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
    Et la je me prend la classique exception:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    cvc-elt.1: Impossible de trouver la d?claration de l'?l?ment 'Toto'.
    Mais la où ça devient intéressant, c'est que si je prend mon DOM et que je le dump dans un fichier en utilisant javax.xml.transform.Transformer. Et que ensuite je charge ce fichier dans un DOM et que je le valide avec exactement le même code, la ça marche.

    Toutes aides est la bienvenue.

    Merci d'avance,
    Olivier.

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Attr xsi = outputDocument.createAttributeNS(xmlnsUri, "xmlns:xsi");
    Un truc comme ça devrait méchamment faire conflit avec la gestion normale des namespaces.

    On ne doit pas déclarer les namespaces en "ajoutant un attribut qui le déclare". L'implémentation de Document est censée s'en charger toute seule.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    C'est ce que je me suis dis aussi mais si j'enlève le namespace devant le nom de mes attributs, je prend un exception:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    org.w3c.dom.DOMException: NAMESPACE_ERR: La tentative de cr‚ation ou de modification de l'objet n'est pas conforme … la syntaxe des espaces de noms.

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Je m'en doute bien, mais ce sont les xmlns:* qu'il ne faut pas mettre. Ce ne sont pas des attributs, ce sont des déclarations de namespace. Ce n'est pas à toi de les gérer, donc.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre éclairé

    Profil pro
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    Justement c'est ça que je dis, quand j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Attr xsi = outputDocument.createAttributeNS(xmlnsUri, "xsi");
    C'est la que je me mange l'exception.

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Pour l'amour du ciel, vire cette ligne. Je dois le dire en quelle langue que tu fais un truc que tu es pas censé faire ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    Soit! J'ai enlevé la la création de l'attribut xmlns:xsi. Et effectivement, il le créé tout seul. J'avais mal interprété ta remarque.

    Cependant, cela ne change rien à mon problème initial.

  8. #8
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Ah... Et si tu réessaies de l'écrire dans un fichier, puis charger ce fichier et le valider, ça continue de marcher dans ce cas-là seulement ?

    Parce que ça, c'est typique d'une confusion dans les namespaces... Et elles-mêmes, sont typiques du fait d'avoir essayé d'insérer les xmlns et xmlns:truc soi-même.
    Il y en a peut-être juste d'autres. Fais voir le programme minimaliste, mais complet.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre éclairé

    Profil pro
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    Ok! Je vais faire un programme minimaliste qui tente de reproduire l'erreur.

    Mais, je n'est pas d'autre utilisation des namespaces. Toutes les autres balises et attribut de mon XML sont créés sans namespace (i.e. createElement et createAttribute tout court sans NS). Et la validation du fichier se fait toujours sans problème. L'éditeur d'Eclipse s'en sort d'ailleurs très bien.

  10. #10
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Dans ce cas cela dépasse ce que j'ai déjà pu voir par moi-même.

    En reproduisant le problème de mon côté j'y verrai peut-être plus clair.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre éclairé

    Profil pro
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    Voici un code minimaliste qui reproduit l'erreur, chez moi en tous cas.
    Le Java
    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
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
     
    package com.afklm.sesame.share.test.business.module.parser;
     
    import java.io.File;
    import java.io.IOException;
    import java.io.StringWriter;
     
    import javax.xml.XMLConstants;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Result;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerConfigurationException;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;
    import javax.xml.validation.Schema;
    import javax.xml.validation.SchemaFactory;
    import javax.xml.validation.Validator;
     
    import org.w3c.dom.Attr;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.xml.sax.SAXException;
     
    /**
     * Test class
     */
    public class ValidationExample {
     
      /**
       * The DOM
       */
      private Document outputDocument;
     
      /**
       * Create the DOM outputDocument programmaticaly
       */
      private void loadXmlDom() {
        try {
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
     
          factory.setNamespaceAware(true);
          factory.setValidating    (true);
     
          Source schemaFile = new StreamSource(new File("data/toto.xsd"));
     
          SchemaFactory sfactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
     
          Schema schema = sfactory.newSchema(schemaFile);
     
          factory.setSchema(schema);
     
          DocumentBuilder builder = factory.newDocumentBuilder();
     
          outputDocument = builder.newDocument();
     
          Element outputRoot = outputDocument.createElement("Toto");
     
          String xsiUri = "http://www.w3.org/2001/XMLSchema-instance";
     
          Attr location = outputDocument.createAttributeNS(xsiUri, "xsi:noNamespaceSchemaLocation");
     
          location.setValue("toto.xsd");
     
          outputRoot.setAttributeNodeNS(location);
     
          outputDocument.appendChild(outputRoot);
     
          Element titi1 = outputDocument.createElement("Titi");
          Element titi2 = outputDocument.createElement("Titi");
     
          Node titi1Text = outputDocument.createTextNode("Titi1");
          Node titi2Text = outputDocument.createTextNode("Titi2");
     
          titi1.appendChild(titi1Text);
          titi2.appendChild(titi2Text);
     
          outputRoot.appendChild(titi1);
          outputRoot.appendChild(titi2);
     
        } catch (ParserConfigurationException e) {
          e.printStackTrace();
        } catch (SAXException e) {
          e.printStackTrace();
        }
      }
     
      /**
       * Dumps the DOM to the stdout
       */
      private void domDump() {
        try {
          TransformerFactory factory = TransformerFactory.newInstance();
     
          Transformer transformer = factory.newTransformer();
     
          transformer.setOutputProperty(OutputKeys.INDENT                          , "yes");
          transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"  );
     
          StringWriter stringWriter = new StringWriter(            );
          Result       result       = new StreamResult(stringWriter);
     
          transformer.transform(new DOMSource(outputDocument), result);
     
          System.out.println(stringWriter.getBuffer().toString());
     
        } catch (TransformerConfigurationException e) {
          e.printStackTrace();
        } catch (TransformerException e) {
          e.printStackTrace();
        }
      }
     
      /**
       * Validates the DOM
       */
      private void validateDom() {
        try {
          SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
     
          Source schemaFile = new StreamSource(new File("data/toto.xsd"));
     
          Schema schema = factory.newSchema(schemaFile);
     
          Validator validator = schema.newValidator();
     
          validator.validate(new DOMSource(outputDocument));
        } catch (SAXException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
     
      /**
       * Main
       * 
       * @param args input arguments (not used)
       */
      public static void main(String[] args) {
        ValidationExample test = new ValidationExample();
     
        test.loadXmlDom();
     
        test.domDump();
     
        test.validateDom();
      }
     
    }
    Et le XSD:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    	<xs:element name="Toto">
    		<xs:complexType>
    			<xs:sequence>
    				<xs:element name="Titi" type="xs:string" />
    			</xs:sequence>
    		</xs:complexType>
    	</xs:element>
    </xs:schema>
    Merci de ton aide.

  12. #12
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Hum. Effectivement, la validation échoue parce qu'il y a deux éléments <Titi> alors qu'il ne peut y en avoir qu'un (heeeere, we are! Born to be kings we're the princes of the universe).

    Ceci étant dit, l'erreur obtenue est :

    cvc-complex-type.2.4.d: Invalid content was found starting with element 'Titi'. No child element is expected at this point.
    Et surtout, cela reste pareil si j'enregistre le fichier sur disque, que je le reload et que je le valide tout pareil.

    Edit : là comme ça je soupçonne que tu ne charges pas le même fichier XSD dans les deux cas. Et que pour valider le document construit par DOM, tu n'utilises pas celui que tu nous as montré.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Membre éclairé

    Profil pro
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    Donc tu n'as pas l'erreur "cvc-elt.1: Impossible de trouver la d?claration de l'?l?ment 'Toto'"?
    Je dois avoir une merde quelque part dans mon environnement. Le fait que la validation sort une erreur n'est pas en problème en soit pour moi, à partir du moment ou l'erreur n'est pas cvc-elt.1.

    Ben de toutes façons je dois abandonner les XSD, je ne peux finalement pas faire ce que je voulais avec. J'ai besoin de valider mon document différemment en fonction de la valeur d'une balise et apparemment c'est pas possible.

Discussions similaires

  1. Réponses: 0
    Dernier message: 28/09/2008, 13h59
  2. Passage de org.w3c.dom.document à XML
    Par Ikare dans le forum Flex
    Réponses: 2
    Dernier message: 03/06/2008, 19h07
  3. [DOM] org.w3c.dom.Document toujours vide
    Par LGnord dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 05/12/2007, 14h45
  4. Créer un org.w3c.dom.Document depuis une String
    Par BouB dans le forum Format d'échange (XML, JSON...)
    Réponses: 8
    Dernier message: 22/06/2007, 17h02
  5. [DOM] Récupérer contenu d'un objet de type org.w3c.dom.Document dans une chaine de caractèr
    Par danyboy85 dans le forum Format d'échange (XML, JSON...)
    Réponses: 4
    Dernier message: 18/01/2007, 11h38

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