2008-10-09 3 views
5

J'essaie de définir un schéma pour les documents XML que je reçois.Schéma XML pour les éléments ayant le même nom mais une sous-structure différente selon le contexte

Les documents ressemblent:

<root> 
    <items> 
     <group name="G-1"> 
      <item name="I-1"/> 
      <item name="I-2"/> 
      <item name="I-3"/> 
      <item name="I-4"/> 
     </group> 
    </items> 
    <data> 
     <group name="G-1" place="here"> 
      <customer name="C-1"> 
       <item name="I-1" count="3"/> 
       <item name="I-2" count="4"/> 
      </customer> 
      <customer name="C-2"> 
       <item name="I-3" count="7"/> 
      </customer> 
     </group> 
    </data> 
</root> 

J'ai essayé XMLSpy et xsd.exe de .NET 2.0. Les deux ont créé des définitions de schéma qui permettent ci-dessous <group> un nombre quelconque d'éléments <item> et <customer>. Mais ce que je cherche devrait limiter <group> ci-dessous <items> à <item> éléments, et <group> ci-dessous <data> à <customer> éléments.

Est-ce quelque chose que le schéma xml n'est pas capable du tout?

Répondre

3

Oui, XSD peut gérer cela. J'ai généré ce schéma à partir de Visual Studio 2008 (beaucoup plus rapide que de le faire à la main) et il fera ce que vous cherchez:

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="root"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="items"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="group"> 
       <xs:complexType> 
        <xs:sequence> 
        <xs:element maxOccurs="unbounded" name="item"> 
         <xs:complexType> 
         <xs:attribute name="name" type="xs:string" use="required" /> 
         </xs:complexType> 
        </xs:element> 
        </xs:sequence> 
        <xs:attribute name="name" type="xs:string" use="required" /> 
       </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     <xs:element name="data"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="group"> 
       <xs:complexType> 
        <xs:sequence> 
        <xs:element maxOccurs="unbounded" name="customer"> 
         <xs:complexType> 
         <xs:sequence> 
          <xs:element maxOccurs="unbounded" name="item"> 
          <xs:complexType> 
           <xs:attribute name="name" type="xs:string" use="required" /> 
           <xs:attribute name="count" type="xs:unsignedByte" use="required" /> 
          </xs:complexType> 
          </xs:element> 
         </xs:sequence> 
         <xs:attribute name="name" type="xs:string" use="optional" /> 
         </xs:complexType> 
        </xs:element> 
        </xs:sequence> 
        <xs:attribute name="name" type="xs:string" use="required" /> 
        <xs:attribute name="place" type="xs:string" use="required" /> 
       </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 
+0

Pas de problème! Heureux de vous aider. –

6

Les points clés (voir XML Schema Runtime Polymorphism via xsi:type and Abstract Types pour le contexte complet et correct/placement/utilisation) sont:

  1. Créer un type de base avec (abstract = "true" pour l'empêcher d'être utilisé directement)

    note: l'attribut ref remplace l'attribut name pour les éléments définis ailleurs

    <xs:complexType name="CustomerType" abstract="true" > 
        <xs:sequence> 
        <xs:element ref="cust:FirstName" /> 
        <xs:element ref="cust:LastName" /> 
        <xs:element ref="cust:PhoneNumber" minOccurs="0"/> 
        </xs:sequence> 
        <xs:attribute name="customerID" type="xs:integer" /> 
    </xs:complexType> 
    
  2. Création de deux ou plusieurs types réalisés par l'extension ou la restriction du type de base

    <xs:complexType name="MandatoryPhoneCustomerType" > 
        <xs:complexContent> 
        <xs:restriction base="cust:CustomerType"> 
         <xs:sequence> 
         <xs:element ref="cust:FirstName" /> 
         <xs:element ref="cust:LastName" /> 
         <xs:element ref="cust:PhoneNumber" minOccurs="1" /> 
         </xs:sequence> 
        </xs:restriction> 
        </xs:complexContent> 
    </xs:complexType> 
    

    et

    <xs:complexType name="AddressableCustomerType" > 
        <xs:complexContent> 
        <xs:extension base="cust:CustomerType"> 
         <xs:sequence> 
         <xs:element ref="cust:Address" /> 
         <xs:element ref="cust:City" /> 
         <xs:element ref="cust:State" /> 
         <xs:element ref="cust:Zip" /> 
         </xs:sequence> 
        </xs:extension> 
        </xs:complexContent> 
    </xs:complexType> 
    
  3. de référence du type de base dans un élément

    <xs:element name="Customer" type="cust:CustomerType" /> 
    
  4. Dans votre document XML, spéci fy type dérivé spécifique comme attribut xsi: type

    <cust:Customer customerID="12345" xsi:type="cust:MandatoryPhoneCustomerType" > 
        <cust:FirstName>Dare</cust:FirstName> 
        <cust:LastName>Obasanjo</cust:LastName> 
        <cust:PhoneNumber>425-555-1234</cust:PhoneNumber> 
    </cust:Customer> 
    

    ou:

    <cust:Customer customerID="67890" xsi:type="cust:AddressableCustomerType" > 
        <cust:FirstName>John</cust:FirstName> 
        <cust:LastName>Smith</cust:LastName> 
        <cust:Address>2001</cust:Address> 
        <cust:City>Redmond</cust:City> 
        <cust:State>WA</cust:State> 
        <cust:Zip>98052</cust:Zip> 
    </cust:Customer> 
    
Questions connexes