我有一个程序,它使用XML格式的规则为运行时创建可执行代码。我必须使用自己的方言定义一些动作和逻辑结构。我有OR,AND,和NOT构造,现在我需要实现IF..THEN..ELSE。
我正在努力想出一个有意义的语法,这就是我到目前为止所拥有的:
<IF id='if-1'>
<TIME from="5pm" to="9pm" />
</IF>
<THEN id='if-1'>
<...some actions defined.../>
</THEN>
<ELSE id='if-1'>
<...other set of actions defined here.../>
</ELSE>
如果看起来很难读,但我没有看到更清晰的方式来代表这一点而不做太多的嵌套。有没有人有建议? (此时不使用XML不是一种选择:))
答案 0 :(得分:9)
也许用XML编码条件结构的另一种方法:
<rule>
<if>
<conditions>
<condition var="something" operator=">">400</condition>
<!-- more conditions possible -->
</conditions>
<statements>
<!-- do something -->
</statements>
</if>
<elseif>
<conditions></conditions>
<statements></statements>
</elseif>
<else>
<statements></statements>
</else>
</rule>
答案 1 :(得分:8)
我个人认为if / then / else需要以某种方式链接。
<IF something>
<some actions>
<THEN something>
<some actions>
</THEN>
<ELSE something>
<some actions>
</ELSE>
</IF>
答案 2 :(得分:4)
前面遇到类似的问题,我决定采用带有条件执行的手臂式指令集来推广“switch ... case ... break ... default”类型解决方案。使用嵌套堆栈的自定义解释器用于解析这些“程序”。此解决方案完全避免了id或标签。我的所有XML语言元素或“指令”都支持“条件”属性,如果不存在,或者如果它的计算结果为true,则执行元素的指令。如果有一个“exit”属性求值为true且条件也为真,则同一嵌套级别的以下元素/指令组既不会被计算也不会被执行,并且执行将继续执行下一个元素/指令。父级。如果没有“退出”或计算结果为假,则程序将继续执行下一个元素/指令。例如,您可以编写这种类型的程序(提供noop“语句”非常有用,并且将值和/或表达式赋值给“变量”的机制/指令将非常方便):
<ins-1>
<ins-11 condition="expr-a" exit="true">
<ins-111 />
...
</ins11>
<ins-12 condition="expr-b" exit="true" />
<ins-13 condition="expr-c" />
<ins-14>
...
</ins14>
</ins-1>
<ins-2>
...
</ins-2>
如果expr-a为真,则执行顺序为:
ins-1
ins-11
ins-111
ins-2
如果expr-a为false且expr-b为true,则它将为:
ins-1
ins-12
ins-2
如果expr-a和expr-b都为假,那么我们将:
ins-1
ins-13 (only if expr-c evaluates to true)
ins-14
ins-2
PS。我使用“exit”而不是“break”,因为我使用“break”来实现“断点”。如果没有某种断点/跟踪机制,这些程序很难调试。
PS2。因为我有与你的例子类似的日期时间条件以及其他类型的条件,我还实现了两个特殊属性:“from”和“until”,如果存在,还必须评估为true,就像“条件”一样,并使用特殊的快速日期时间检查逻辑。
答案 3 :(得分:2)
<IF id='if-1'>
<CONDITION>
<TIME from="5pm" to="9pm" />
</CONDITION>
<THEN>
<...some actions defined.../>
</THEN>
<ELSE>
<...other set of actions defined here.../>
</ELSE>
</IF>
似乎更容易给我读。还有更多的嵌套,但是如果有什么有助于提高可读性呢?
答案 4 :(得分:2)
我不认为你可以设计if-then-else结构而不考虑其他结构的设计。我认为每个表达式应该是一个元素是一个很好的原则,它的子表达式应该是子元素。然后有关于元素名称是否应该反映它的表达类型或者它相对于父元素的角色的问题。或者你可以做到这两点:
<if>
<condition>
<equals>
<number>2</number>
<number>3</number>
<equals>
<condition>
<then>
<string>Mary</string>
</then>
<else>
<concat>
<string>John</string>
<string>Smith</string>
</concat>
</else>
</if>
但是你有时可以使用省略角色名称(条件,然后是其他)的设计,并依赖于元素相对于父元素的位置重要性。这取决于你想要保持简洁的程度。
答案 5 :(得分:0)
我认为你必须记住的事情是你的XML是由机器而不是人来处理的,所以它只需要对机器可读。
换句话说,我认为您应该使用所需的任何XML模式,以便在运行时尽可能高效地解析/处理规则。
就您当前的架构而言,我认为每个元素的id
属性应该是唯一的,因此您可能应该使用不同的属性来捕获IF
,{{1}之间的关系}和THEN
元素。
答案 6 :(得分:0)
<IF id="if-1">
<TIME from="5pm" to="9pm" />
<ELSE>
<something else />
</ELSE>
</IF>
我不知道这对其他人是否有任何意义,或者它在您的程序中实际可用,但我会这样做。
我的观点:您需要在IF标签中包含与“IF”相关的所有内容,否则您将无法知道ELSE属于哪个IF。其次,我会跳过THEN标记,因为它始终跟在IF之后。
答案 7 :(得分:0)
就个人而言,我更喜欢
<IF>
<TIME from="5pm" to="9pm" />
<THEN>
<!-- action -->
</THEN>
<ELSE>
<!-- action -->
</ELSE>
</IF>
通过这种方式,您不需要使用id
属性将IF
,THEN
,ELSE
标记绑定在一起
答案 8 :(得分:0)
<IF>
<CONDITIONS>
<CONDITION field="time" from="5pm" to="9pm"></CONDITION>
</CONDITIONS>
<RESULTS><...some actions defined.../></RESULTS>
<ELSE>
<RESULTS><...some other actions defined.../></RESULTS>
</ELSE>
</IF>
这是我的看法。这将允许您有多个条件。