【问题标题】:Traceability with XSDXSD 的可追溯性
【发布时间】:2010-06-11 18:44:09
【问题描述】:

我试图让我的 XML 模式处理一些可追溯性功能,因为我在阅读一些功能规范时正在收集需求。 (对于需求管理来说并不理想,但至少是一个开始。)

我正在做的是为我目前正在阅读的每个功能规范创建一个 functionalSpec> 标记。我为找到的每个需求创建了一个 requirement> 标签。由于我希望能够跟踪需求的来源,因此我使用 functionalSpec> 的 id 创建了一个 trace> 元素元素。我不想让自己在 functionalSpecId> 标记中输入任何纯旧文本,而是希望 XSD 验证并确保我只输入存在于现有的功能规范。我的问题出现在XML Schema W3C Recommendations 文档似乎说我想做的事情是不可能的。 (大约下降 1/2)

{selector} 指定一个受限的 XPath ([XPath]) 表达式相对于被声明元素的实例。这必须标识约束适用的从属元素的节点集(即包含在声明的元素中)。

我使用 Oxygen 来创建它,因为我对 XSD 文件还很陌生,它给了我以下错误:

E [Xerces] 身份约束错误:身份约束“KeyRef@1045a2”有一个 keyref 引用了超出范围的键或唯一键。

所以我的问题是,有没有人知道一种方法可以让我通过使用 XSD 来使用与下面相同的 XML 结构?

下面是 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>

下面是 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>

【问题讨论】:

    标签: xml xsd requirements traceability


    【解决方案1】:

    我很确定我已经完成了您在这里想要实现的目标。 诀窍是在更高级别定义唯一、键和 keyref 约束(在您的情况下为 srs 元素)。 下面是一些代码示例,用于检查是否已在 item/@name 中定义了“requires”元素:

    注意约束是如何在项目级别定义的。

    <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 示例:

    <?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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多