根据xsd 1.1

时间:2015-06-17 16:01:23

标签: xml xsd

我需要在我的XSD架构中定义以下情况。这是我的XML的一个例子:

<initialization>

  <stat name="SelfActualization" range="" init="" tickValue="" colorR="" colorG="" colorB=""/>
  <stat name="Social" range="" init="" tickValue="" colorR="" colorG="" colorB=""/>

  <staticAction name="Study" >
    <SelfActualization reqPoints="0" gainedPoints="0" />
    <Social reqPoints="0" gainedPoints="0" />
  </staticAction>

  <staticAction name="Greetings" >
    <SelfActualization reqPoints="0" gainedPoints="0" />
    <Social reqPoints="0" gainedPoints="0" />
  </staticAction>

  <staticAction name="Eat" >
    <SelfActualization reqPoints="0" gainedPoints="0" />
    <Social reqPoints="0" gainedPoints="0" />
  </staticAction>

</initialization>

我需要的第一个断言:我可以定义尽可能多的&#34; stat&#34;我想要的元素(在这种情况下只有2),我已经设法获得这种行为。我不知道该怎么做的是:在我的任何一个静态行动&#34;我需要所有的&#34;统计数据&#34;以前定义的上面再次命名(作为元素,这是我已经通过xs:anyType元素做的事情,但我需要一个控制名称对应的断言),并且它们在开头定义它们的顺序相同。 正如我们在示例中所看到的那样,确实都是&#34; SelfActualization&#34;和#34;社交&#34;在我的所有StaticActions中都有正确的顺序。如果是另一个&#34; stat&#34;以前没有定义,或者如果其中一个&#34;统计数据&#34;如果缺少定义,或者如果顺序错误,则必须拒绝XML。到目前为止,我的XSD看起来像这样:

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

<xs:element name="initialization" type="initializationType" />

<xs:complexType name="initializationType">
  <xs:sequence>
    <xs:element  minOccurs="0" maxOccurs="unbounded" ref="stat"/>
    <xs:element  minOccurs="0" maxOccurs="unbounded" ref="staticAction"/>
  </xs:sequence>
</xs:complexType>

<xs:element name="staticAction" type="StaticActionType"/>

<xs:complexType name="StaticActionType">
    <xs:complexContent>
        <!-- Base is anyType -->
        <xs:extension base="xs:anyType">
            <xs:attribute name="name" type="xs:string"/>
            <!-- Check that every "dynamic" child has the two integer attributes and no other attributes -->
            <xs:assert test="every $element in ./* satisfies 
                ($element[
                    matches(@reqPoints, '^[+-]?\d+$') and
                    matches(@gainedPoints, '^[+-]?\d+$') and
                    count(@*=2)])"/>
            <!-- Test that there is no content in staticAction nor in the "dynamic" nodes -->
            <xs:assert test="matches(string(.), '^\s*$')"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

我需要的第二个断言:我通过使用一个简单的xs:序列在我的xsd模式的开头声明StaticActions,因为我需要一定数量的那些并按特定顺序。在那里,我想确保这些staticActions具有正确的名称(通过staticAction定义中指定的&#34; name&#34;属性):例如,我想要&#34; Study&#34; &#34;问候&#34;和&#34;吃&#34; 。因此,我需要在我的XML中检查所有这三个&#34; Study&#34;,&#34; Greetings&#34;和&#34;吃&#34;在那里,通过一个简单的断言。

编辑:最后一点是:我的staticAction除了动态之外还需要包含2个静态元素,如下例所示:

<initialization>

  <stat name="SelfActualization" range="" init="" tickValue="" colorR="" colorG="" colorB=""/>
  <stat name="Social" range="" init="" tickValue="" colorR="" colorG="" colorB=""/>

  <staticAction name="Study" >
    <SelfActualization reqPoints="0" gainedPoints="0" />
    <Social reqPoints="0" gainedPoints="0" />

    <RequiredAction action="string" cardinality="int" />
    <SuccessLikelihood likelihood="int" />
  </staticAction>

因此我需要修改我对#34; StaticAction&#34;的定义。并修改一些检查staticAction的所有子节点的断言。

1 个答案:

答案 0 :(得分:1)

对于第一个requeriment,您可以在 initializationType 中使用以下断言:

<xs:assert test="every $staticAction in ./staticAction satisfies deep-equal(data($staticAction/*/name()), data(./stat/@name)) "/>

这可确保每个staticAction包含节点名称等于同一顺序中stat元素的属性名称的子节点。

对于第二个要求,您可以使用这个简单的断言,假设订单不重要且值可以重复:

<xs:assert test="every $staticAction in ./staticAction satisfies $staticAction/@name = ('Study', 'Greetings', 'Eat') "/>

这也可以在XSD中进行调节:

<xs:attribute name="name">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:enumeration value="Study"/>
            <xs:enumeration value="Greetings"/>
            <xs:enumeration value="Eat"/>
        </xs:restriction>
    </xs:simpleType>
</xs:attribute>

否则,如果值不能重复但必须出现,则可以使用三个不同的断言来确保每个值都存在一次(例如:count(./staticAction[@name='Eat']) = 1)。