2009-05-31 5 views
3

Je voudrais créer un XSD qui définit un attribut qui peut être placé sur des éléments d'autres schémas, ou des éléments qui ne sont pas dans un schéma. Par exemple, le schéma ressemblerait à quelque chose comme ceci:Puis-je créer un schéma XSD qui place un attribut sur tous les types complexes?

<xs:schema id="MySchema" 
    targetNamespace="http://tempuri.org/MySchema" 
    elementFormDefault="qualified" 
    xmlns="http://tempuri.org/MySchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
> 
    <xs:attribute name="myAttribute" /> 
</xs:schema> 

Et le document pourrait ressembler à ceci:

<someElement xmlns="http://tempuri.org/OtherSchema" xmlns:m="http://tempuri.org/MySchema"> 
    <someOtherElement someAttribute="value" m:myAttribute="value2" /> 
</someElement> 

"OtherSchema" pour cet exemple ressemble à ceci:

<xs:schema id="OtherSchema" 
    targetNamespace="http://tempuri.org/OtherSchema" 
    elementFormDefault="qualified" 
    xmlns="http://tempuri.org/OtherSchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
> 
    <xs:element name="someElement"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="unbounded" name="someOtherElement"> 
      <xs:complexType> 
      <xs:attribute name="someAttribute" /> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Un exemple complet, comprenant une application console C# effectuant une validation, peut être téléchargé à partir du http://dl.getdropbox.com/u/407740/SchemaTest.zip. Mon but est de le faire valider sans avoir à modifier "OtherSchema". Est-ce possible?

+0

Est-ce que someElement, someOtherElement et someAttribute sont définis dans OtherSchema? Je pense que vous voulez que myAttribute soit requis sur * tous * les éléments, sans qu'il soit défini sur ces éléments. Cela me semble impossible. Je l'ai essayé, et bien sûr ça ne marche pas. John dit que cela fonctionne pour xsi: nil etc, mais ils sont intégrés dans le monde XML Schema, et pourraient être (et ressembler) à des cas spéciaux pour moi, comme suggéré par jelovirt. – 13ren

+0

Oui, autant que je sache, les attributs de l'instance de schéma sont gérés spécialement. Je peux construire un OtherSchema qui rend l'exemple ci-dessus valide, mais je voudrais que cela fonctionne sans avoir à modifier OtherSchema. –

+0

@jon s'il vous plaît ajouter un exemple complet qui devrait faire ce que vous voulez, mais pas, de sorte qu'il peut être exécuté directement. C'est-à-dire, un "OtherSchema", les espaces de noms qui fonctionnent, et tout ce qui est nécessaire, donc il peut simplement être coupé et collé. Je pense que c'est une question intéressante, mais elle est aussi assez sophistiquée et abstraite, et cela vous aidera beaucoup si vous la rendez aussi concrète et précise que possible. – 13ren

Répondre

1

je devais ajouter un emballage, pour importer les deux schémas différents en un seul (car xmllint accepte qu'un seul schéma XML):

<xs:schema id="Wrapper" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:import schemaLocation="MySchema.xsd" namespace="http://tempuri.org/MySchema"/> 
    <xs:import schemaLocation="OtherSchema.xsd" namespace="http://tempuri.org/OtherSchema"/> 
</xs:schema> 

La seule façon que je pourrais obtenir quelque chose comme la question au travail était de modifier OtherSchema, XSD (ce qui est interdit par la question), donc ajouter un caractère générique d'attribut (après l'existant):

<xs:attribute name="someAttribute" /> 
<xs:anyAttribute namespace="##other"/> 

Je ne suis pas assez d'un expert de XML Sch ema de dire "c'est impossible", mais cela me semble impossible.

Un problème avec votre proposition est que vous ne spécifiez pas le nouvel attribut devrait apparaître. Habituellement, si vous déclarez un attribut (ou un complexElement, un groupe de modèles, etc.), vous êtes libre de vous y référer ou non. Si vous n'y parlez pas explicitement, cela n'a aucun effet. Par conséquent, je pense que votre proposition sera traitée comme un attribut déclaré, mais non mentionné. Ce que vous voulez vraiment, c'est une manière de dire "ajouter cet attribut à tous les existants complexType" - mais vous ne dites pas cela. Et, malheureusement, il ne semble pas y avoir de moyen de le dire. (Il n'y a même pas un moyen de dire "ajouter cet attribut à ce complexType existant existant" - vous devez l'inclure dans la définition originale ou pas du tout.)

Une façon de en partie<redefine> types dans un autre schéma - Je vais ajouter cela dans une deuxième réponse.

-1

Considérons xsi: nil, xsi: schemaLocation et xsi: noNamespaceSchemaLocation. La réponse est oui.

Il n'aurait pas fallu longtemps pour l'essayer et voir.


Il vous manquait un targetNamespace dans le schéma. Essayez ceci:

<xs:schema xmlns="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="MySchema"> 
    <xs:attribute name="myAttribute" /> 
</xs:schema> 
+0

Tous vos exemples proviennent de l'espace de noms d'instance XML Schema, attributs utilisés par XML Schema lui-même. Pourriez-vous donner un exemple de schéma OtherSchema qui permettra les attributs MySchema sans les déclarer dans OtherSchema? – jelovirt

+0

Peu importe. Essayez-le et découvrez-le. –

+0

L'exemple était en fait un schéma et un document séparé. J'ai mis à jour la question pour refléter cela. Le fait est que je n'ai aucun contrôle sur le contenu d'OtherSchema. Je veux que cet attribut puisse être placé sur n'importe quel élément indépendamment de la façon dont il est défini dans le schéma dont il provient. Évidemment, l'exemple ne fonctionne pas ou je n'aurais pas eu de question. Que suggérez-vous que j'essaie? –

0

Vous pouvez redéfinir le schéma, en les étendant comme bon vous semble. De cette manière, vous pouvez modifier les définitions d'un schéma existant sans modifier le fichier. MAIS IL NE FONCTIONNERA PAS POUR VOTRE EXEMPLE comme donné, car on ne peut pas redéfinir les éléments (seulement les types complexes, etc. voir http://www.w3.org/TR/xmlschema-1/#element-redefine).Par conséquent, j'ai décomposé votre exemple en types complexes explicites, afin qu'ils soient exposés pour une redéfinition.

RedefineOtherSchema.xsd:

<xs:schema id="RedefineOtherSchema" 
    targetNamespace="http://tempuri.org/OtherSchema" 
    elementFormDefault="qualified" 
    xmlns="http://tempuri.org/OtherSchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:m="http://tempuri.org/MySchema">   <!-- for the ref --> 

    <xs:import schemaLocation="MySchema.xsd" 
    namespace="http://tempuri.org/MySchema"/>  <!-- import --> 

    <xs:redefine schemaLocation="OtherSchema.xsd"> <!-- redefine --> 
    <xs:complexType name="SomeOtherElement"> 
     <xs:complexContent> 
     <xs:extension base="SomeOtherElement"> 
      <xs:attribute ref="m:myAttribute" />  <!-- the ref --> 
     </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 
    </xs:redefine> 
</xs:schema> 

OtherSchema:

<xs:schema id="OtherSchema" 
    targetNamespace="http://tempuri.org/OtherSchema" 
    elementFormDefault="qualified" 
    xmlns="http://tempuri.org/OtherSchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
> 
    <xs:element name="someElement" type="SomeElement"/> 

    <xs:complexType name="SomeElement"> 
     <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="unbounded" 
        name="someOtherElement" type="SomeOtherElement"/> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="SomeOtherElement"> 
     <xs:attribute name="someAttribute" /> 
    </xs:complexType> 
</xs:schema> 

MySchema: (inchangé)

<xs:schema id="MySchema" 
    targetNamespace="http://tempuri.org/MySchema" 
    elementFormDefault="qualified" 
    xmlns="http://tempuri.org/MySchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
> 
    <xs:attribute name="myAttribute"/> 
</xs:schema> 

Pourquoi <complexContent>? La redéfinition doit être une extension (ou une restriction) du type existant - c'est comme cela qu'elle modifie la définition précédente. L'extension doit être en <complexContent> (je crois).

Pourquoi <import>? Vous ne pouvez pas définir des objets dans plus d'un espace de noms dans un fichier xsd (il n'y a qu'un seul "targetNamespace"). Mais vous pouvez contourner cela en important une définition à partir d'un autre fichier xsd (alors vous ne l'avez pas "défini"). [Est il y a une autre façon?]

HTH :-)

+0

C'est une approche intéressante et il est possible que je sois capable de l'adapter à ce que j'essaie de faire. Il place toujours des contraintes sur le schéma tiers car vous ne pouvez pas redéfinir un type en ligne (et le schéma particulier avec lequel je travaille en a plusieurs). Mais, on dirait que vous avez raison de dire que mon objectif initial n'est pas réalisable, et c'est une bonne solution de contournement. –

+0

Je suis d'accord: il est courant de définir des éléments à la place des types, et les éléments ne peuvent pas être définis. BTW: Je pense que les types qui sont en ligne dans une définition de type de niveau supérieur (pas un élément de haut niveau) peuvent être redéfinis, en redéfinissant le type à l'intérieur de .... (Je ne l'ai pas essayé, mais il a un sens), mais cela n'aide pas pour les éléments de haut niveau autant que je peux voir. – 13ren

+0

Cela vaut la peine de poser des questions sur la liste de diffusion xml-dev (il y a quelques experts en la matière, y compris certains des auteurs de XML Schema). La fonctionnalité que vous voulez serait très utile - peut-être qu'ils ont une solution de contournement. – 13ren

0

C'est exactement ce NVDL (validation basée Namespace et dispatching Language) fournit. Il permet de combiner plusieurs schémas/vocabulaires pour valider un document sans avoir besoin de modifier ces schémas. NVDL est une norme ISO.

Un travail de script NVDL qui gère votre cas est inférieure

<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0" startMode="other"> 
    <mode name="other"> 
    <namespace ns="http://tempuri.org/OtherSchema"> 
     <validate schema="other.xsd" useMode="validateMyAttributes"/> 
    </namespace> 
    </mode> 
    <mode name="validateMyAttributes"> 
    <namespace ns="http://tempuri.org/MySchema" match="attributes"> 
     <validate schema="my.xsd"/> 
    </namespace> 
    </mode> 
</rules> 

Fondamentalement, il dit valider ce qu'il est sur le ... namespace tempuri.org/OtherSchema avec le schéma other.xsd et les attributs de. ..tempuri.org/MySchema avec le schéma my.xsd.

Pour plus d'informations sur NVDL, voir www.nvdl.org. Le script ci-dessus a été testé avec oNVDL.

Questions connexes