web-dev-qa-db-fra.com

XSD avec des éléments d'un autre espace de noms

J'ai deux XSD qui définissent des documents différents. Dire A.xsd définit un élément ElementA comme racine, avec quelques règles complexes. Maintenant B.xsd définit un élément ElementB qui est censé utiliser ElementA quelque part entre les deux.

Par exemple, je veux que le fichier XML pour ElementB ressemble à ceci:

<?xml version="1.0" encoding="utf-8"?>
<ElementB xmlns="http://example.com/namespace/for/ElementB">
  <foo>Bla</foo>
  <bar>Blub</bar>
  <ElementA xmlns="http://example.com/namespace/for/ElementA">
    <!-- ... -->
  </ElementA>
</ElementB>

Ensuite B.xsd pourrait ressembler à ceci:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://example.com/namespace/for/ElementB" targetNamespace="http://example.com/namespace/for/ElementB" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="ElementB">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="foo" type="xs:string" />
        <xs:element name="bar" type="xs:string" />

        <!-- And now I want to include ElementA somehow -->
        <xs:element name="ElementA" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Le fait est que je ne veux pas vraiment cloner la spécification de ElementA dans B.xsd, comme il existe également des documents, qui ont simplement ElementA comme racine (c'est-à-dire ElementB est une sorte de document conteneur).

Alors, comment puis-je autoriser ElementA dans ElementB tout en construisant complètement sur le XSD déjà existant?

21
poke

Il existe en fait deux façons différentes de composer des documents de schéma XML: <xs:import> et <xs:include>. xs: include est destiné à être utilisé lorsque l'espace de noms du document contenant est le même que celui référencé, ce n'est donc pas tout à fait ce que vous recherchez. xs: import est mieux adapté à votre situation lorsque vous devez référencer tous (ou un sous-ensemble) des éléments du schéma référencé et qu'ils se trouvent dans un espace de noms cible différent. Il y a une question ici sur les différences: Quelle est la différence entre xsd: include et xsd: import? .

Quoi qu'il en soit, revenons à cette question précise. Ce que vous voulez probablement, c'est quelque chose comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema 
    xmlns="http://example.com/namespace/for/ElementB"
    targetNamespace="http://example.com/namespace/for/ElementB"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    xmlns:ea="http://example.com/namespace/for/ElementA">
 <xs:import namespace="http://example.com/namespace/for/ElementA" schemaLocation="A.xsd" /> 
 <xs:element name="ElementB">
  <xs:complexType>
   <xs:sequence>
    <xs:element name="foo" type="xs:string" />
    <xs:element name="bar" type="xs:string" />
    <!-- This introduces a element named ElementA that uses the ComplexType ea:ElementA defined in A.xsd -->
    <xs:element name="ElementA" type="ea:ElementA" />
   </xs:sequence>
  </xs:complexType>
 </xs:element>
</xs:schema>

Bien que vous ayez besoin de A.xsd pour créer un type complexe pour ElementA que vous pouvez utiliser dans B.xsd comme indiqué.

Cet arcticle contient de bonnes informations/exemples et inclut une discussion sur certaines des différentes stratégies de composabilité: http://www.xfront.com/ZeroOneOrManyNamespaces.html

33
daveaglick

Vous pouvez utiliser <xsd:import> tag pour importer un schéma avec un autre espace de noms.

1
Alexander Yezutov