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

Valider XML Discussion :

[XSD] structure récursive et clés, un casse-tête


Sujet :

Valider XML

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut [XSD] structure récursive et clés, un casse-tête
    Bonjour à tous,

    Je suis confronté à un petit problème avec les schémas et je me reporte à votre grande expérience et sagesse dans le domaine pour m’aider à le résoudre ;-) J’utilise le XML pour les données d’entrées d’un programme que j’ai écrit en C++ pour la manipulation de graphes. Je vous donne le code du schéma (que j’ai simplifié au maximum : ne vous inquiétez pas si vous trouvez certaines structures inutilement complexes : j’ai enlevé beaucoup d’éléments non pertinents pour le problème).

    Dans mon schéma, un arbre (arc = relation, nœud = paramètre) est défini de manière récursive comme suit :

    - Une relation de base appelée rootRelation est le premier élément de l’arbre.
    - Ensuite chaque relation est composée :

    o D’un élément rootParameter (type string) désignant le paramètre parent de l’arbre : il est obligatoire

    o Dans le cas d’une branche avec un seul descendant nous trouvons un élément subParameter (type string) et subRelation désignant respectivement le paramètre fils et la relation de plus bas niveau

    o De la même manière pour les branches avec deux descendants nous avons deux paramètres (type string) et deux sous-relations

    o Dans le cas où il n’y a pas de successeur, seul le paramètre rootParameter est présent dans l’élément structure.

    Une liste de paramètres au même niveau que rootRelation contient tous les paramètres du modèle avec pour chacun d’eux un élément unique /name/ (type string).

    Le but que je recherche est double :

    - Chaque paramètre de /parameterList/ doit posséder un /name/ unique

    - Chaque paramètre utilisé dans l’arbre (soit rootParameter, subParameter, subParameter1 et subParameter2) doit correspondre à un paramètre défini dans la liste des paramètres.

    Pour cela j’utilise le mécanisme de clés sur la liste de paramètres (garantit bien l’unicité de la valeur du paramètre ciblé c’est-à-dire /name/) et la référence à la clé via un chemin de localisation xpath. Le problème c’est que ça marche bien pour l’unicité du nom des paramètres (key) mais pour les keyrefs je suis obligé de spécifier le chemin xpath complet ce qui ne me permet pas d’atteindre tous les éléments rootParameter et subParameter puisque la structure est récursive mais pas le chemin (dans l’exemple je désigne le premier rootParameter comme simple exemple).

    Si quelqu’un pouvait m’aider à résoudre ce problème combiné de déclaration récursive et d’unicité des valeurs dans une telle structure, je lui en serais fort reconnaissant J

    Merci d’avance ;-)
    Alexis

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        
        <xs:element name="relation">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="rootRelation" type="relationType">
                        
                    </xs:element>
                    <xs:element name="parameterList" type="parameterListType">
                        
                    </xs:element>
                    
                    
                </xs:sequence>
            </xs:complexType>
            <xs:key name="parameterKey">
                <xs:selector xpath="./parameterList/parameter"></xs:selector>
                <xs:field xpath="name"></xs:field>
            </xs:key>
            <xs:keyref refer="parameterKey" name="parameterKeyRef">
                <xs:selector xpath="./rootRelation/structure"></xs:selector>
                <xs:field xpath="rootParameter"></xs:field>
            </xs:keyref>
            
        </xs:element>
        
        <xs:complexType name="relationType">
            <xs:sequence minOccurs="1" maxOccurs="1">
                <xs:element name="structure"><xs:complexType>
                    <xs:sequence>
                        <xs:element name="rootParameter" type="xs:string">
                            
                        </xs:element>
                        <xs:choice minOccurs="0" maxOccurs="1">          
                            <xs:sequence>
                                <xs:element name="subRelation" type="relationType">
                                    
                                </xs:element>
                                <xs:element name="subParameter" type="xs:string">
                                    
                                </xs:element>
                            </xs:sequence>
                            <xs:sequence>
                                <xs:element name="subRelation1" type="relationType">
                                    
                                </xs:element>
                                <xs:element name="subParameter1" type="xs:string">
                                    
                                </xs:element>
                                <xs:element type="relationType" name="subRelation2">
                                    
                                </xs:element>
                                
                                <xs:element name="subParameter2" type="xs:string">
                                    
                                </xs:element>
                            </xs:sequence>
                        </xs:choice>
                        
                    </xs:sequence>
                </xs:complexType>
                    
                </xs:element>
            </xs:sequence>
            
        </xs:complexType>
        <xs:complexType name="parameterListType">
            <xs:sequence>
                <xs:element minOccurs="1" maxOccurs="unbounded" type="parameterType" name="parameter">
                    
                </xs:element>
            </xs:sequence>
        </xs:complexType>
        <xs:complexType name="parameterType">
            <xs:sequence>
                <xs:element name="name" type="xs:string">
                    
                </xs:element>
            </xs:sequence>
        </xs:complexType>
        
    </xs:schema>

  2. #2
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,

    un petit échantillon d'une instance XML valide aiderait à la réflexion, je crois...
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  3. #3
    Rédacteur

    Avatar de Erwy
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2003
    Messages
    4 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 967
    Points : 10 927
    Points
    10 927
    Par défaut
    Citation Envoyé par GrandFather
    Bonjour,

    un petit échantillon d'une instance XML valide aiderait à la réflexion, je crois...
    Ah! j' suis pas le seul alors ...

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Hello,

    Merci pour vos réponses ;-) En effet ce n’est peut-être pas facile sans exemple d’une instance ;-) Voici un petit exemple d’un arbre simple :

    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
     
    <rootRelation>
    <structure>
    <rootParameter>Param1</rootParameter>
    </structure>
    </rootRelation>
     
    <parameterList>
     
    <parameter>
    <name>Param1</name>
    </parameter>
     
    <parameter>
    <name>Param2</name>
    </parameter>
     
    </parameterList>

    Dans mon schéma je mets une clé sur l’élément « name » de parameter. Donc cela garantit l’unicité des noms de paramètre : dans l’exemple ci-dessus si je remplace le nom du deuxième paramètre Param2 par Param1 il ne valide effectivement plus.
    En plus j’ai une référence sur l’élément rootParameter qui pointe vers la clé définie précédemment : donc si je remplace la valeur de rootParameter par autre chose que Param1 ou Param2 il ne valide plus donc ça marche bien jusque là.

    Dans le cas suivant (toujours avec le schéma défini dans mon premier post) :
    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
     
    <structure>
    <rootParameter>Param1</rootParameter>
        <subRelation>
            <structure>
                <rootParameter>Param3</rootParameter>
            </structure>
        </subRelation>
        <subParameter>Param3</subParameter>
     
    </structure>
    </rootRelation>
     
    <parameterList>
     
    <parameter>
    <name>Param1</name>
    </parameter>
     
    <parameter>
            <name>Param2</name>
        </parameter>
     
    </parameterList>

    La validation du document se fait sans problème alors qu’apparaît deux fois la valeur Param3 qui n’existe pas comme valeur dans les clés. Et c’est normal parce qu’aucune référence ne pointe vers la clé pour subParameter. Si je rajoute la référence suivante alors le document ne se valide plus (comme je le désire) parce que la valeur Param3 de subParameter n’est pas définie dans la liste des paramètres :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     <xs:keyref refer="parameterKey" name="parameterKeyRef2">
                <xs:selector xpath="./rootRelation/structure"></xs:selector>
                <xs:field xpath="subParameter"></xs:field>
            </xs:keyref>
    Mais le problème est que la structure arborescente qui contient les éléments sur lesquels je mets des références est définie de manière récursive : je ne sais donc pas a priori combien « d’étages » elle aura et je devrais donc définir un nombre infini de références en prévision, chacune allant plus loin dans l’arborescence (pour le fils de l’élément racine, le fils du fils de l’élément racine, etc.) :-/ J’ai essayé de définir des références de clé dans la définition du type « relationType » en espérant qu’il soit dupliqué automatiquement pour chaque élément instanciant ce type mais ça ne marche pas (la clé et sa référence doivent être définies au même « endroit » semblerait-il …)
    Donc je cale et je ne sais pas comment m’en sortir …

    Merci d’avance ;-)

  5. #5
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Si je ne m'abuse, cette définition de référence de clé devrait convenir quelle que soit la profondeur de ta structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <xs:keyref refer="parameterKey" name="parameterKeyRef">
      <xs:selector xpath="./rootRelation//rootParameter|./rootRelation//subParameter|./rootRelation//subParameter1|./rootRelation//subParameter2"></xs:selector>
      <xs:field xpath="."></xs:field>
    </xs:keyref>
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par GrandFather
    Si je ne m'abuse, cette définition de référence de clé devrait convenir quelle que soit la profondeur de ta structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <xs:keyref refer="parameterKey" name="parameterKeyRef">
      <xs:selector xpath="./rootRelation//rootParameter|./rootRelation//subParameter|./rootRelation//subParameter1|./rootRelation//subParameter2"></xs:selector>
      <xs:field xpath="."></xs:field>
    </xs:keyref>
    Hello

    Merci pour ta réponse mais ça n'a pas l'air de marcher : il me fait les deux erreurs suivantes lors de la validation du schéma :

    The expression ./rootRelation//rootParameter|./rootRelation//subParameter|./rootRelation//subParameter1|./rootRelation//subParameter2' is not valid with respect to the XPath subset supported by XML Schema.

    Cardinality of Fields for keyref 'parameterKeyRef' and key 'parameterKey' must match each other.

    Je vais regarder en parallèle XPATH dont je ne connais que les bases ...

  7. #7
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Effectivement, au temps pour moi, les expressions XPath que j'ai données (sans les tester), bien que valides, ne sont pas autorisées pour des contraintes d'identité (le // n'est autorisé qu'en début d'expression, juste après le point).

    Celles-ci devraient être correctes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <xs:keyref refer="parameterKey" name="parameterKeyRef">
      <xs:selector xpath=".//rootParameter|.//subParameter|.//subParameter1|.//subParameter2"></xs:selector>
      <xs:field xpath="."></xs:field>
    </xs:keyref>
    Par contre, du fait que ces références sont vérifiées parmi tous les descendants de l'élément <relation>, il ne faut pas que tu aies des éléments <rootParameter>, <subParameter> ,etc. en dehors d'un <rootRelation>.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    En effet c'était ça ^^ J'ai regardé en parallèle et il y a quelques limitations sur XPATH pour l'utilisation dans les clés comme aussi l'impossibilité d'utiliser des prédicats ...

    En tout cas un grand merci pour ton aide précieuse et de t'être penché en détails sur mon problème : c'est super gentil ^^

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

Discussions similaires

  1. [Tableaux] Casse têtes de boucles
    Par Anduriel dans le forum Langage
    Réponses: 5
    Dernier message: 28/06/2006, 00h24
  2. Casse tête chinois
    Par Jahjouh dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 15/03/2006, 09h04
  3. requête SQL un peu casse tête
    Par hellbilly dans le forum Langage SQL
    Réponses: 4
    Dernier message: 15/12/2005, 10h03
  4. Classe, pile, pointeurs et casse-tête!
    Par zazaraignée dans le forum Langage
    Réponses: 6
    Dernier message: 26/09/2005, 16h57
  5. casse-tête excel
    Par gregius dans le forum Access
    Réponses: 2
    Dernier message: 21/09/2005, 16h38

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