3

小 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

4 回答 4

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)

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

于 2014-02-10T10:07:09.033 回答
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>

于 2012-04-06T22:11:25.910 回答
1

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

于 2012-04-06T22:36:55.540 回答
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>
于 2018-09-10T07:48:05.543 回答