2010-09-02 7 views
4

Est-il possible avec le schéma XML de restreindre la profondeur des éléments enfants imbriqués dans un parent?Limiter la profondeur des éléments imbriqués dans XSD

Le contexte ici est de recueillir des alarmes à partir d'un système de gestion et je souhaite fournir un document XML qui permet à l'utilisateur final de définir certaines règles afin de filtrer les alarmes dans des dossiers dans l'interface utilisateur. Je veux limiter la profondeur des dossiers imbriqués à 3 afin qu'un utilisateur final ne puisse pas imbriquer des centaines de niveaux profonds - car le filtrage de tant de niveaux entraînerait le blocage éventuel de l'application.

Je pourrais écrire du code pour gérer ceci, mais il semble approprié de le définir dans le schéma si c'est possible.

Par exemple, ce serait bien:

<group name="Folder 1"> 
     <group name="Folder 2"> 
      <group name="Folder 3"> 
       <group name="Folder 4"> 
       </group> 
      </group> 
     </group> 
    </group> 

Ce serait invalide, comme le dossier 5 est trop profond. Mon schéma ressemble à ceci, mais ne limite pas la profondeur de l'extrait ci-dessus.

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:element name="hierarchy"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="group" type="GroupType" /> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" /> 
    </xs:complexType> 
    </xs:element> 

    <xs:complexType name="GroupType"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="group" type="GroupType" /> 
    </xs:sequence> 
    <xs:attribute name="name" type="xs:string" use="required" /> 
    <xs:attribute name="filterOn" type="xs:string" use="optional" /> 
    <xs:attribute name="operator" type="xs:string" use="optional" /> 
    <xs:attribute name="value" type="xs:string" use="optional" /> 
    </xs:complexType> 
</xs:schema> 

Des pointeurs très appréciés!

Répondre

4

Une solution simple et jolie n'est pas disponible dans XML Schema (mais dans d'autres langages) mais vous pouvez y arriver, en imbriquant vous-même tout ce que je ne peux pas recommander.

Donc, si je vous, je ferais une des deux choses:

  1. Choisissez une alternative au schéma XML (ou une extension) Voir: http://en.wikipedia.org/wiki/XML_schema#XML_schema_languages (un coup d'oeil à RELAX et Schematron)
  2. Effectuez la vérification de profondeur dans votre application et rejetez-la si depth > 3 et désactivez le comportement dans la documentation de votre schéma XML et de votre application.

Citation de Wiki sur XML Schema version 1.1 (recommandation candidat):

La possibilité de définir des affirmations contre le contenu du document au moyen d'expressions XPath 2.0 (une idée empruntée à Schematron)

< - Cela rendra la profondeur assez facile à définir.

Pour des commentaires sur la façon de représenter la profondeur d'imbrication dans XMLSchema:

Fondamentalement, vous pouvez faire quelque chose comme ce qui suit (en recommandant toujours le faire dans le code). Vous pouvez ensuite ajouter des attributs, ajuster la profondeur, etc. (vous pouvez peut-être réutiliser les attributs avec extension ou restrict mais je ne suis pas sûr à 100%).Cette méthode peut être assez méchant (exponentielle) si vous permettez plusieurs types de sous-éléments:

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema elementFormDefault="qualified" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://somenamespace.com" 
      xmlns="http://somenamespace.com"> 

    <xs:element name="hierarchy"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="group" type="GroupTypeDepth0" /> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" /> 
    </xs:complexType> 
    </xs:element> 

    <xs:complexType name="GroupTypeDepth0"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="group" type="GroupTypeDepth1" /> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="GroupTypeDepth1"> 
    <xs:sequence> 
     <xs:element minOccurs="0" maxOccurs="1" name="group" type="GroupTypeDepth2" /> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="GroupTypeDepth2"/> 
</xs:schema> 

valides:

<hierarchy xmlns="http://somenamespace.com"> 
    <group> 
    <group> 
     <group/> 
    </group> 
    </group> 
</hierarchy> 

non valides:

<hierarchy xmlns="http://somenamespace.com"> 
    <group> 
    <group> 
     <group> 
     <group/> 
     </group> 
    </group> 
    </group> 
</hierarchy> 
+0

Comment puis-je imbriquer le schéma pour atteindre cet? Malheureusement, je dois utiliser un schéma XML pour cela car je ne peux pas ajouter les bibliothèques tierces (application Java) nécessaires pour prendre en charge RELAX/Schematron en raison de considérations de licence. Je finirai probablement par devoir écrire un code très peu élégant pour supporter cela, même si la solution du schéma est désordonnée, c'est peut-être le moindre de deux maux. – tja

+0

@tja voir mise à jour :) –

+0

parfait, je prends votre point sur l'élégance (ou le manque de). – tja

Questions connexes