2010-06-11 4 views
4

J'essaie de laisser mon schéma XML gérer une petite fonctionnalité de traçabilité car je rassemble les exigences tout en lisant certaines spécifications fonctionnelles. (Pas idéal pour la gestion des exigences, mais au moins son début.)Traçabilité avec XSD

Ce que je fais est la création d'une balise < functionalSpec> pour chaque spécification fonctionnelle je suis en train de lire à travers. Je crée une étiquette de < > pour chaque exigence que je trouve. Puisque je veux être en mesure de retracer où l'exigence est venu, je crée une trace < > élément avec l'id de l'élément < functionalSpec>. Au lieu de me permettre d'entrer tout texte ancien dans la balise < functionalSpecId>, je veux que le XSD valide et m'assure que je ne saisis qu'un id qui existe pour une spécification fonctionnelle existante. Mon problème vient où il semble que la documentation XML Schema W3C Recommendations dit que ce que je veux faire n'est pas possible. (Environ 1/2 chemin vers le bas)

{selector} specifies a restricted XPath ([XPath]) expression relative to instances of the element being declared. This must identify a node set of subordinate elements (i.e. contained within the declared element) to which the constraint applies.

J'utilise l'oxygène pour créer cela depuis que je suis assez nouveau pour les fichiers XSD, et il me donne l'erreur suivante:

E [Xerces] Identity Constraint error: identity constraint "[email protected]" has a keyref which refers to a key or unique that is out of scope.

Donc, mon question est de savoir quelqu'un d'un moyen qui me permettra d'utiliser la même structure XML que j'ai ci-dessous en utilisant XSD?

Ci-dessous le fichier XML.

<?xml version="1.0" encoding="UTF-8" ?> 

<srs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="srs req2.xsd" 
    xmlns="srs"> 

<requirements> 

<requirement DateCreated="2010-06-11" id="1"> 
    <Text>The system shall...</Text> 
    <trace> 
     <functionalSpecId>B010134</functionalSpecId> 
    </trace> 
    <revisions> 
     <revision date="2010-06-11" num="0"> 
      <description>Initial creation.</description> 
     </revision> 
    </revisions> 
</requirement> 

</requirements> 

<functionalSpecs> 

    <functionalSpec id="B010134" model="Model-T"> 
     <trace> 
      <meeting></meeting> 
     </trace> 
     <revisions> 
      <revision date="2009-07-08" num="0"> 
       <description>Initial creation.</description> 
      </revision> 
      <detailer>Me</detailer> 
      <engineer>Me</engineer> 
     </revisions> 
    </functionalSpec> 

</functionalSpecs> 
</srs> 

est Ci-dessous le fichier XSD.

<?xml version="1.0" encoding="UTF-8" ?> 

<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="srs" 
    xmlns="srs" 
    xmlns:srs="srs" 
    elementFormDefault="qualified"> 

    <!-- SRS --> 

    <xs:element name="srs" type="SRSType"> 
    </xs:element> 

    <xs:complexType name="SRSType"> 
    <xs:sequence> 
     <xs:element ref="requirements" /> 
     <xs:element ref="functionalSpecs" /> 
    </xs:sequence> 
    </xs:complexType> 

    <!-- Requirements --> 

    <xs:element name="requirements" type="RequirementsType"> 
    <xs:unique name="requirementId"> 
     <xs:selector xpath="srs/requirements/requirement" /> 
     <xs:field xpath="@id" /> 
    </xs:unique> 
    </xs:element> 

    <xs:complexType name="RequirementsType"> 
    <xs:choice maxOccurs="unbounded"> 
     <xs:element name="requirement" type="RequirementType" /> 
    </xs:choice> 
    </xs:complexType> 

    <xs:complexType name="RequirementType"> 
    <xs:complexContent> 
     <xs:extension base="RequirementInfo"> 
     <xs:sequence> 
      <xs:element name="trace" type="TraceType" maxOccurs="unbounded" minOccurs="1" /> 
      <xs:element name="revisions" type="RequirementRevisions" /> 
     </xs:sequence> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="RequirementRevisions"> 
    <xs:sequence> 
     <xs:element name="revision" type="RevisionInfo" minOccurs="1" maxOccurs="unbounded" /> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="RequirementInfo"> 
    <xs:sequence> 
     <xs:element name="Text" type="Description" /> 
    </xs:sequence> 
    <xs:attribute name="DateCreated" type="xs:date" use="required" /> 
    <xs:attribute name="id" type="xs:integer" use="required" /> 
    </xs:complexType> 

    <!-- Functional Specs --> 

    <xs:element name="functionalSpecs" type="FunctionalSpecsType"> 
    <xs:unique name="functionalSpecId"> 
     <xs:selector xpath="srs/functionalSpecs/functionalSpec" /> 
     <xs:field xpath="@id" /> 
    </xs:unique> 
    </xs:element> 

    <xs:complexType name="FunctionalSpecsType"> 
    <xs:choice maxOccurs="unbounded"> 
     <xs:element name="functionalSpec" type="FunctionalSpecType" /> 
    </xs:choice> 
    </xs:complexType> 

    <xs:complexType name="FunctionalSpecType"> 
    <xs:complexContent> 
     <xs:extension base="FunctionalSpecInfo"> 
     <xs:sequence> 
      <xs:element name="trace" type="TraceType" maxOccurs="unbounded" minOccurs="1" /> 
      <xs:element name="revisions" type="FunctionalSpecRevisions" /> 
     </xs:sequence> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="FunctionalSpecRevisions"> 
    <xs:sequence> 
     <xs:element name="revision" type="RevisionInfo" minOccurs="1" maxOccurs="unbounded" /> 
     <xs:element name="detailer" type="xs:string" /> 
     <xs:element name="engineer" type="xs:string" /> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="FunctionalSpecInfo"> 
    <xs:attribute name="id" type="xs:string" use="required" /> 
    <xs:attribute name="model" type="xs:string" use="required" /> 
    </xs:complexType> 

    <!-- Requirements, Functional Specs --> 

    <xs:complexType name="TraceType"> 
    <xs:choice> 
     <xs:element name="requirementId"> 
     <xs:keyref refer="requirementId" name="requirementIdRef"> 
      <xs:selector xpath="srs/requirements/requirement" /> 
      <xs:field xpath="@id" /> 
     </xs:keyref> 
     </xs:element> 
     <xs:element name="functionalSpecId"> 
     <xs:keyref refer="functionalSpecId" name="functionalSpecIdRef"> 
      <xs:selector xpath="srs/functionalSpecs/functionalSpec" /> 
      <xs:field xpath="@id" /> 
     </xs:keyref> 
     </xs:element> 
     <xs:element name="meeting" /> 
    </xs:choice> 
    </xs:complexType> 

    <!-- Common --> 

    <xs:complexType name="RevisionInfo"> 
    <xs:choice> 
     <xs:element name="description" type="Description" /> 
    </xs:choice> 
    <xs:attribute name="date" type="xs:date" use="required" /> 
    <xs:attribute name="num" type="xs:integer" use="required" /> 
    </xs:complexType> 

    <xs:complexType name="Description" mixed="true"> 
    <xs:simpleContent> 
     <xs:extension base="xs:string"> 
     <xs:attribute name="Date" type="xs:date" /> 
     </xs:extension> 
    </xs:simpleContent> 
    </xs:complexType> 

</xs:schema> 

Répondre

3

Je suis sûr que j'ai déjà fait ce que vous essayez d'accomplir ici. L'astuce consiste à définir les contraintes uniques, key et keyref à un niveau supérieur (élément srs dans votre cas). Voici un exemple de code qui vérifie que les éléments "requires" ont été définis dans un élément/@ name:

Notez comment les contraintes sont définies au niveau des éléments.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> 
    <xs:element name="item"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="special" minOccurs="0" maxOccurs="unbounded"/> 
       <xs:element ref="requires" minOccurs="0" maxOccurs="unbounded"/> 
      </xs:sequence> 
      <xs:attribute name="name" type="xs:string" use="required"/> 
      <xs:attribute name="mana" type="xs:int"/> 
      <xs:attribute name="life" type="xs:int"/> 
      <xs:attribute name="manaRegen" type="xs:int"/> 
      <xs:attribute name="hitRegen" type="xs:int"/> 
      <xs:attribute name="damage" type="xs:int"/> 
      <xs:attribute name="armor" type="xs:int"/> 
      <xs:attribute name="attackSpeed" type="xs:int"/> 
      <xs:attribute name="moveSpeed" type="xs:int"/> 
      <xs:attribute name="str" type="xs:int"/> 
      <xs:attribute name="agi" type="xs:int"/> 
      <xs:attribute name="int" type="xs:int"/> 
      <xs:attribute name="cost" type="xs:int" use="required"/> 
      <xs:attribute name="image"/> 
     </xs:complexType> 
    </xs:element> 
    <xs:element name="items"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="shop" maxOccurs="unbounded"/> 
      </xs:sequence> 
      <xs:attribute name="version" type="xs:string"/> 
     </xs:complexType> 
     <xs:unique name="uniqueItemNames"> 
      <xs:selector xpath="shop/item"/> 
      <xs:field xpath="@name"/> 
     </xs:unique> 
     <xs:unique name="uniqueShopNames"> 
      <xs:selector xpath="shop"/> 
      <xs:field xpath="@name"/> 
     </xs:unique> 
     <xs:key name="itemKey"> 
      <xs:selector xpath="shop/item"/> 
      <xs:field xpath="@name"/> 
     </xs:key> 
     <xs:keyref name="requiresValue" refer="itemKey"> 
      <xs:selector xpath="shop/item/requires"/> 
      <xs:field xpath="."/> 
     </xs:keyref> 
    </xs:element> 
    <xs:element name="requires" type="xs:string"/> 
    <xs:element name="shop"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="item" maxOccurs="unbounded"/> 
      </xs:sequence> 
      <xs:attribute name="name" type="xs:string" use="required"/> 
     </xs:complexType> 
    </xs:element> 
    <xs:simpleType name="specialType"> 
     <xs:restriction base="xs:string"> 
      <xs:enumeration value="Activate"/> 
      <xs:enumeration value="Aura"/> 
      <xs:enumeration value="Effect"/> 
      <xs:enumeration value="Orb"/> 
      <xs:enumeration value="Info"/> 
     </xs:restriction> 
    </xs:simpleType> 
    <xs:element name="special"> 
     <xs:complexType> 
      <xs:simpleContent> 
       <xs:extension base="xs:string"> 
        <xs:attribute name="type" type="specialType" use="required"/> 
        <xs:attribute name="mana" type="xs:int"/> 
        <xs:attribute name="cooldown" type="xs:int"/> 
        <xs:attribute name="chance" type="xs:int"/> 
       </xs:extension> 
      </xs:simpleContent> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

XML Exemple:

<?xml version="1.0" encoding="UTF-8"?> 
<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="dota.xsd" version="6.52d"> 
    <shop name="Leragas The Vile"> 
     <item name="Demon's Edge" image="FrostMourne.gif" cost="2600" damage="36"/> 
     <item name="Eaglehorn" image="INV_Weapon_Bow_06.gif" cost="3300" agi="25"/> 
     <item name="Messerschmidt's Reaver" image="SpiritWalkerMasterTraining.gif" cost="3200" str="25"/> 
     <item name="Sacred Relic" image="StaffOfTeleportation.gif" cost="3800" damage="60"/> 
     <item name="Hyperstone" image="Periapt1.gif" cost="2100" attackSpeed="55"/> 
     <item name="Ring of Health" image="GoldRing.gif" cost="875" hitRegen="5"/> 
     <item name="Void Stone" image="Periapt.gif" cost="875" manaRegen="100"/> 
     <item name="Mystic Staff" image="StaffOfNegation.gif" cost="2700" int="25"/> 
     <item name="Energy Booster" image="EnchantedGemstone.gif" cost="1000" mana="250"/> 
     <item name="Point Booster" image="UsedSoulGem.gif" cost="1200" life="200" mana="150"/> 
     <item name="Vitality Booster" image="SoulGem.gif" cost="1100" life="250"/> 
    </shop> 
    <shop name="Level 1 (Human) Recipes"> 
     <item name="Perseverance" image="OrbOfFire.gif" cost="0" damage="10" hitRegen="5" manaRegen="125"> 
      <requires>Ring of Health</requires> 
      <requires>Void Stone</requires> 
     </item> 
     <item name="Headdress of Rejuvenation" image="INV_Helmet_17.gif" cost="225" agi="2" int="2" str="2"> 
      <special type="Aura">+2 HP/Sec regen (500 AoE)</special> 
      <requires>Ring of Regeneration</requires> 
      <requires>Ironwood Branch</requires> 
     </item> 

    </shop> 

</items>