如何有效地模拟XML中的逻辑/布尔表达式?

时间:2012-04-06 21:53:03

标签: xml boolean-logic

这里的小xml建模练习。

假设我们有一些逻辑表达式:    (x& y)| (p& q)

并且无论出于何种原因,都需要用XML表示。

这是一个快速刺,但我认为这很笨:

 <expr>
    <or>
        <and>
            <e>x</e>
            <e>y</e>
        </and>
        <and>
            <e>p</e>
            <e>q</e>
        </and>
    </or>
 </expr>

另一种刺痛,对我来说没有味道:

<expr>
    <or>
        <and l="x" r="y"/>
        <and l="p" r="q"/>
    </or>
</expr>

你会怎么做?

4 个答案:

答案 0 :(得分:5)

Armatus的回答对我来说很好看。我认为左右元素是多余的。有一个逻辑表达式,如果我左右或左右评估它们并不重要。

 <expr type="or">
    <expr type="and">
        <sig>x</sig>
        <sig>y</sig>
    </expr>
    <expr type="and">
        <sig>p</sig>
        <sig>q</sig>
    </expr>
</expr>

例如:   (x & y) | (p & q)(q & p) | (y & x)

相同

此外,它可以添加两个以上的信号。

答案 1 :(得分:4)

这个怎么样?

<expr:or>
<l>
    <expr:and>
    <l>x</l><r>y</r>
    </expr>
</l>
<r>
    <expr:and>
    <l>p</l><r>q</r>
    </expr>
</r>
</expr>

还可以添加<expr:xor><l>x</l><r>y</r></expr><expr:not>x</expr>

答案 2 :(得分:1)

你的第一个“快速刺”对我来说看起来非常合理,除了外部'expr'元素,它不会增加太多价值。

答案 3 :(得分:0)

看看在Microsoft .NET的System.Linq.Expressions名称空间中如何建模表达式树是很有趣的。我认为在这里很重要的基本概念是,所有内容都继承自基本的Expression类-几乎所有内容都是表达式,可以是二进制运算,参数,常量等。

此外,NuGet软件包Serialize.Linq演示了如何将这样的表达式树序列化为XML。

长期解决方案

尽管这仅供参考。我认为XML模型可以变得更简单。我会像这样为您的示例建模:

<expr returns="boolean">
  <params>
    <param name="x" type="boolean">
    <param name="y" type="boolean">
    <param name="p" type="boolean">
    <param name="q" type="boolean">
  </params>
  <body op="bor">
    <left op="band">
      <left  op="param">x</left>
      <right op="param">y</left>
    </left>
    <right op="band">
      <left  op="param">p</left>
      <right op="param">q</left>
    </right>
  </body>
<expr>

简短解决方案

根据您的实现,您也许可以省略<params>元素和type属性,并在解释表达式时以更“隐式”的方式处理这些事情(类似于JavaScript,PowerShell ,...)。另外,如果XML输出的大小/长度成问题,则可以使元素和类型的名称更短。

因此,这是高度简化版本的和示例:

<e t="bor">
  <l t="band">
    <l t="prm">x</l>
    <r t="prm">y</r>
  </l>
  <r t="band">
    <l t="prm">p</l>
    <r t="prm">y</r>
  </r>
</e>

另一个示例

为了完整起见,这是另一个示例,说明如何以这种方式对更复杂的表达式进行建模。

伪代码lambda /箭头表达式:

(float b, int e) => e == 0 ? 1 : (e == 1 ? b : pow(b, e))

XML表示形式

<expr returns="float">
 <params>
   <prm name="b" type="float" />
   <prm name="e" type="int" />
 </params>
 <body op="if">
   <cond op="eq">
     <left op="param">e</left>
     <right op="const" type="int">0</right>
   </cond>
   <true op="const" type="float">1</true>
   <false op="if">
     <cond op="eq">
       <left op="param">e</left>
       <right op="const" type="int">1</right>
     </cond>
     <true op="param">b</true>
     <false op="call" name="pow">
       <args>
         <arg op="param">p</arg>
         <arg op="param">e</arg>
       </args>
     </false>
   </false>
 </body>
</expr>