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

XML/XSL et SOAP Discussion :

xsd:all sur des éléments de type différents


Sujet :

XML/XSL et SOAP

  1. #1
    Membre du Club
    Profil pro
    Développeur Full Stack
    Inscrit en
    Mars 2009
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Full Stack

    Informations forums :
    Inscription : Mars 2009
    Messages : 94
    Points : 69
    Points
    69
    Par défaut xsd:all sur des éléments de type différents
    Bonjour,

    J'ai un soucis de validation d'un fichier XML par un XSD. J'ai comme exemple le XML suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <conf>
        <params>
            <attr key="myNumber">1</attr>
            <attr key="machin">example</attr>
            <attr key="bidule">example2</attr>
        </params>
    </conf>
    Si besoin la structure du XML peut être modifiée pour valider toutes les règles ci-dessous

    Mon XSD doit valider les points suivants :
    1. On peut définir (fixed) le valeur d'un attribut et appliquer des restrictions pour un <attr> qui porte cette valeur. Exemple : "Si ma key est "id" alors la valeur de mon <attr> est un integer".
    2. Si un <attr> est défini (fixed) alors on peut préciser si il est optionnel ou non dans le document. Exemple : "Mon <attr> de key "id" est obligatoire et est de type integer, mon <attr> de key "weight" est optionnel mais si il existe dans le document il doit être de type integer et compris entre 0 et 100"
    3. Tous les <attr> ont une structure par défaut (ici ils s'appellent <attr> et ont un attribut key obligatoire). Tous les <attr>, même si non définis, qui apparaissent doivent respecter cette structure de base.
    4. L'ordre d'apparition des <attr> importe peu, mon <attr> id peut très bien arriver avant ou après "weight" dans l'odre de lecture.
    5. Règle optionnelle : un <attr> donné ne peut apparaitre qu'une seule et unique fois dans le document.


    J'en suis arrivé à quelque chose qui me permet de valider le contenu de l'élément en fonction de la valeur de la key (ci-dessous). Mais le problème est si j'inverse deux éléments, deux attr, même si leur type est bien différent et même avec le xs:all, la validation ne passe pas. Dès que je respecte de nouveau l'ordre d’apparition du type de mes attr cela passe. Comment faire pour que la validation passe sans se soucier de l'ordre d'apparation du type de mes attr ?

    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
     
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:complexType name="attrMyNumberType">
            <xs:simpleContent>
                <xs:extension base="xs:integer">
                    <xs:attribute name="key" fixed="myNumber" />
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
     
    <xs:complexType name="attrMachinType">
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute name="key" fixed="Machin" />
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
     
    <xs:complexType name="attrBiduleType">
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute name="key" fixed="Bidule" />
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
     
     
                    <xs:element name="conf">          
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="params">          
                                    <xs:complexType>
                                        <xs:all minOccurs="0">
                                            <xs:element name="attr" type="attrMyNumberType"/>
                                            <xs:element name="attr" type="attrMachinType"/>
                                            <xs:element name="attr" type="attrBiduleType"/>
                                        </xs:all>
                                    </xs:complexType> 
                                </xs:element> 
                            </xs:sequence>
                        </xs:complexType>          
                    </xs:element>
    </xs:schema>
    Merci

  2. #2
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    [0]
    <xs:all minOccurs="0">
    <xs:element name="attr" type="attrMyNumberType"/>
    <xs:element name="attr" type="attrMachinType"/>
    <xs:element name="attr" type="attrBiduleType"/>
    </xs:all>
    Avec ce genre de construction, le schema n'arriverait à se valider avant de valider une instance de xml. Mais, c'est un peu plus compliqué à expliquer.

    [0.1] En w3c schema v1.0, il est incorrect d'avoir des éléments dans la même portée locale d'avoir le même nom mais avec different type: il se peut qu'il est besoin un peu plus de nuance modulo les constructions de substitutionGroup etc, mais en gros c'est ça et c'est très strict.

    [0.2] En w3c schema v1.1, c'est possible mais la syntaxe est très différente, donc, je peux raisonnablement supposer vous vous travillez dans la cadre de v1.0.

    [1] Pour la raison [0.1], on n'arriverait pas à construire un schema pour tous les fins en même temps.

    [1.1] Supposons que on se contente à imposer seulement la condition sur la portée de valeurs pour le key et la condition sur le caractère unique que chacun de key dans attr peuve prendre; et on sacrifice les contraintes textuelles de attr, vous pouvez faire ça avec les outils classiques de v1.0 qui n'est toutefois pas si simple pour les non-initiés.
    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
    <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
     
    <xs:element name="conf">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="params" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
     
    <xs:element name="params" type="paramsType">
        <xs:unique name="uniquekey">
            <xs:selector xpath="attr" />
            <xs:field xpath="@key" />
        </xs:unique>
    </xs:element>
     
    <xs:complexType name="paramsType">
        <xs:sequence>
            <xs:element ref="attr" minOccurs="3" maxOccurs="3" />
        </xs:sequence>
    </xs:complexType>		
     
    <xs:element name="attr">
        <xs:complexType>
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute name="key" type="keyType" />
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    </xs:element>
     
    <xs:simpleType name="keyType">
        <xs:restriction base="xs:token">
            <xs:enumeration value="myNumber" />
            <xs:enumeration value="machin" />
            <xs:enumeration value="bidule" />
        </xs:restriction>
    </xs:simpleType>
     
    </xs:schema>
    [2] Toujour restant dans v1.0 et prenant la structure particulière de ce genre de xml, dites, les valeurs de clé sont myNumber ou machin ou bidule qui sont elles-mêmes capable d'être un nom NCName de balises: on peut faire ça.

    [2.1] D'abord pré-procès l'instance de xml pour ramener la forme d'attr en laissant tombé la constance attr.

    [2.1.1] l'original
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <conf>
        <params>
            <attr key="myNumber">1</attr>
            <attr key="machin">example</attr>
            <attr key="bidule">example2</attr>
        </params>
    </conf>
    [2.1.1] le document transformé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <conf>
        <params>
            <myNumber>1</myNumber>
            <machin>example</machin>
            <bidule>example2</bidule>
        </params>
    </conf>
    [2.2] Alors comme ça, c'est tout à fait possible de construire un schema constant pour valider le document transformé. Par conséquence, le document est ainsi validé lui aussi.

    [2.3] Il peut appaître fantaciste pour faire une suite de processus comme ça pour faire une validation; mais, c'est pourtant faissable et pratiqué dans bien des cas dans certain domaine comme dsig... sinon des cas sans ce genre de bel nom. Ce n'est pas si irréal que ça paraît au premier moment.

    [2.4] Si on fait valider en tandem w3c schema + schematron, c'est aussi une possibilité. Le fil conducteur est en fait un peu le même avec [2.3] en appellant secours au xslt.

    [2.5] Et puis, preque complètement différent, vous pouvez regarder l'approche de RelaxNg. C'est faissable mais c'est plus héterogène. C'est tout à fait respectable aussi.

    [3] Avec w3c schema v1.1 sur la scène, ce genre de problèmes est complètement résoluable et c'est presque trop facile. Pourtant les implémentations ne sont pas très répandues, mais celle de xerces-j v2.11 est assez, même très, bonne déjà. Mais une expansion sur ce point est trop demandant de ma part sans être préalablement fortement motivé de la faire! Donc, je m'arrêts.

Discussions similaires

  1. Réponses: 37
    Dernier message: 18/05/2008, 23h20
  2. [XSD] comment faire des tests sur des éléments
    Par attila771 dans le forum Valider
    Réponses: 1
    Dernier message: 11/10/2007, 12h32
  3. itération sur des objets de types différents ?
    Par jc63 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 07/09/2007, 08h19
  4. Réponses: 16
    Dernier message: 10/11/2005, 22h51
  5. Réponses: 5
    Dernier message: 13/07/2005, 10h03

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