2010-05-11 4 views
3

Une autre question XSD - comment puis-je obtenir que les éléments XML suivants sont valides:différents sous-éléments en fonction de l'attribut/valeur de l'élément

<some-element> 
    <type>1</type> 
    <a>...</a> 
</some-element> 

<some-element> 
    <type>2</type> 
    <b>...</b> 
</some-element> 

Les sous-éléments (soit<a>ou<b>) devrait dépendre du contenu de <type> (pourrait également être un attribut). Il serait si simple dans RelaxNG - mais RelaxNG ne supporte pas l'intégrité clé :(

est-il un moyen de mettre en œuvre ce dans XSD

Note: XML version du schéma 1.1 prend en charge <xs:alternative>, ce qui pourrait être une solution? , mais autant que je sache aucune implémentation de référence (par exemple libxml2) soutient ce encore Je suis à la recherche de solutions de contournement La seule façon que je suis venu avec est:...

<type>1</type> 
<some-element type="1"> 
    <!-- simple <xs:choice> between <a> and <b> goes here --> 
    <a>...</a> 
</some-element> 
<!-- and now create a keyref between <type> and @type --> 

Répondre

2

non, le schéma XML 1.0 ne peut pas faire

3

La meilleure solution consiste à retirer le <type/> et seulement avoir un xs:choice pour <a/> et <b/> et laisser l'application consommant le XML trier le type.

Une autre solution pourrait être d'avoir un xs:choice pour <a/> et <b/> utiliser un script xslt pour faire une validation de l'élément <type/> par rapport à <a/> et <b/>.

D'abord valider le xml par rapport au xmlschema puis utiliser le xslt pour faire une transformation, si le résultat de la transformation est une chaîne vide, il est valide sinon afficher la chaîne résultante comme un message d'erreur.

Quelque chose comme ça ...

XmlSchema:

<xs:element name="some-element"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="type" type="xs:integer" /> 
     <xs:choice> 
      <xs:element name="a" type="xs:string" /> 
      <xs:element name="b" type="xs:string" /> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:demo="uri:demo:namespace"> 
    <xsl:output method="text" /> 
    <xsl:template match="/demo:some-element"> 
    <xsl:if test="type = 1 and not(demo:a)"> 
     When type equals 1 element a is requred. 
    </xsl:if> 
    <xsl:if test="type = 2 and not(demo:b)"> 
     When type equals 2 element b is requred. 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 
Questions connexes