如何在不使用xsd:sequence的情况下强制执行排序?

时间:2016-03-21 11:27:57

标签: xml xsd xsd-validation xml-validation

我正在编写一个规则引擎,用户可以按任意顺序指定规则,但一旦指定,它们的执行顺序与配置顺序相同。像这样的东西

<RuleEngine>
     <Rule1 ..>
     <Rule2 ..>
     <Rule3 ...>
</RuleEngined>

(执行:Rule1 - &gt; Rule2 - &gt; Rule3

或者喜欢这个

<RuleEngine>
     <Rule3 ..>
     <Rule1 ..>
     <Rule2 ...>
</RuleEngine>

(执行:Rule3 - &gt; Rule1 - &gt; Rule2

我正在为此编写架构,但无法通过xsd:allxsd:sequence获得所需的结果。如果我使用xsd:all,它将为用户提供灵活性,但在解析时不会保留代码中的顺序。

    <xs:element name="RuleEngine">
      <xs:complexType>
         <xs:all>
               <xs:element ref="Rule1" ..
               <xs:element ref="Rule2" ..
               <xs:element ref="Rule3" ..
         </xs:all>
      </xs:complexType>
    </xs:element>

我也不能使用xsd:sequence,否则会阻止用户按照自己选择的顺序指定规则,但在CODE中它会让开发人员知道订单。

    <xs:element name="RuleEngine">
      <xs:complexType>
         <xs:sequence>
               <xs:element ref="Rule1" ..
               <xs:element ref="Rule2" ..
               <xs:element ref="Rule3" ..
         </xs:sequence>
      </xs:complexType>
    </xs:element>

我读了几个帖子,例如thread1thread2似乎没有直接的XML / XSD出路。你既可以强制执行命令也可以不强制执行,也不能像我在做梦一样:) 一个不那么偏好的选择是使用&#34; all&#34;并强制用户将数字ID与规则一起放置,作为代码在执行前对规则进行排序的提示。 其他繁琐的工作是迁移到Boost Property Tree

如果我能用现有框架实现理想的行为,有什么建议吗?

1 个答案:

答案 0 :(得分:1)

这里有很多问题,导致虚假的窘境......

  

如何在不使用序列的情况下强制执行排序?

你没有。您可以使用xs:sequence作为序列。

  

我正在编写一个规则引擎,用户可以在其中指定规则   序列,但一旦指定,它们的执行顺序与   构造

按指定的顺序执行规则不是规则引擎,而是一系列命令式if语句。 ...但这不是您的XML和XSD问题。

  

我也不能使用序列,否则会阻止用户指定   按照他们选择的顺序排列规则,不过在CODE中它会让   开发者知道订单。

在这里,您会感受到XML设计决策将规则编号烘焙到规则元素名称中的负面影响。根本不要这样做。

而不是:

<RuleEngine>
     <Rule1 ..>
     <Rule2 ..>
     <Rule3 ..>
</RuleEngine>

这样做:

<RuleEngine>
     <Rule num="1"  ..>
     <Rule num="2"  ..>
     <Rule num="3"  ..>
</RuleEngine>

或者更好的是,这个:

<RuleEngine>
     <Rule ..>
     <Rule ..>
     <Rule ..>
</RuleEngine>

让规则编号隐含。

然后你的XSD将是微不足道的:

<xs:element name="RuleEngine">
  <xs:complexType>
     <xs:sequence>
       <xs:element ref="Rule" maxOccurs="unbounded"/>
     </xs:sequence>
  </xs:complexType>
</xs:element>