1

I am writing a rule engine where user can specify rules in any sequence but once specified, they are executed in same order as configured. Something like this

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

(Execution : Rule1->Rule2->Rule3)

OR like this

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

(Execution : Rule3->Rule1->Rule2)

I am writing a schema for this and am not able to get desired result with xsd:all or xsd:sequence. If I use xsd:all it will allow flexibility for user but will NOT preserve order in code while parsing.

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

I can't use xsd:sequence either, else it will prevent users from specifying Rules in the order of their choice, though in CODE it will let developer know the order.

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

I read few threads e.g. thread1 , thread2 and it seems there is no direct way out with XML/XSD for this. You can either enforce order OR not enforce it, can't have both like I am dreaming :) One not-so-preferred option is to use "all" and enforce user to put an numeric ID along with the rule, as a hint for code to sort out rules before execution. Other tedious one is to migrate onto Boost Property Tree

Any suggestion if I can achieve desired behavior with existing framework?

Community
  • 1
  • 1
Manish Baphna
  • 422
  • 2
  • 13

1 Answers1

1

There are numerous issues at play here, leading to false quandaries...

How to enforce ordering without using sequence?

You don't. You use xs:sequence for sequences.

I am writing a rule engine where user can specify rules in any sequence but once specified, they are executed in same order as configured.

Executing rules in the order specified is not a rules engine but a sequence of imperative if statements. ...but this is aside from your XML and XSD concerns.

I can't use sequence too, else it will prevent users from specifying Rules in the order of their choice, though in CODE it will let developer know the order.

Here you're feeling negative consequences of your XML design decision to bake rule numbers into rule elements names. Simply don't do that.

Rather than this:

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

Do this:

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

Or better still, this:

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

and let rule numbering be implicit.

Then your XSD would be trivial:

<xs:element name="RuleEngine">
  <xs:complexType>
     <xs:sequence>
       <xs:element ref="Rule" maxOccurs="unbounded"/>
     </xs:sequence>
  </xs:complexType>
</xs:element>
kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • Well, Rule1, Rule2 are not exactly generic 'Rule' with 'number baked in' it. They could be totally 'different' rules like , OR with non uniform structures. So last schema you suggested won't fit in here. Adding "num" explicitly is not preferred as my users would curse me specially if they keep juggling rules and orders. I guess I'll conclude it can't be solved in existing form. TIme to move to Boost PTree ! – Manish Baphna Mar 28 '16 at 13:40
  • The last schema I suggested actually drops the explicit numbering. Rule based systems don't typically rely on ordering except possibly as a tiebreaker in matching. – kjhughes Mar 29 '16 at 01:35