Pyparsing/Python二进制布尔表达式到XML嵌套问题(2.7.10)
我需要将嵌套的二进制布尔表达式解析为XML树。以表达式为例Pyparsing/Python二进制布尔表达式到XML嵌套问题(2.7.10),python,xml,nested,boolean,pyparsing,Python,Xml,Nested,Boolean,Pyparsing,我需要将嵌套的二进制布尔表达式解析为XML树。以表达式为例 expression2 = "((Param1 = 1 AND Param2 = 1 ) \ OR (Param3 = 1 AND Param4 = 1)) \ AND \ (((Param5 = 0 AND Param6 = 1 ) \ OR(Param7 = 0 AND Param8 = 1)) \ AND \
expression2 = "((Param1 = 1 AND Param2 = 1 ) \
OR (Param3 = 1 AND Param4 = 1)) \
AND \
(((Param5 = 0 AND Param6 = 1 ) \
OR(Param7 = 0 AND Param8 = 1)) \
AND \
((Param9 = 0 AND Param10 = 1 ) \
OR(Param11 = 0 AND Param12 = 1)))"
它本质上是(表达式)(运算符)(表达式)
术语的组合
我需要输出是这些表达式与XML中适当标记的组合。阿卡
<MainBody>
<FirstExpression>
Parameter
</FirstExpression>
<Operator>=</Operator>
<SecondExpression>
1
</SecondExpression>
</MainBody>
参数
=
1.
其中firstexpression可以是参数或主体(这里是嵌套),运算符始终为=、AND、or,而secondexpression可以是整数或主体
总是有三个一组的——也就是最小的离散对象将由第一个表达式、运算符和第二个表达式组成
我提出的代码(这是我第一次使用python)让我有点理解
import pyparsing as pp
import xml.etree.ElementTree as ET
operator = pp.Regex(">=|<=|!=|>|<|=").setName("operator").setResultsName("Operator")
number = pp.Regex(r"[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?").setResultsName("SecondExpression")
identifier = pp.Word(pp.alphas, pp.alphanums + "_" + ".").setName("FirstExpression").setResultsName("FirstExpression")
comparison_term = identifier | number
condition = pp.Group(comparison_term + operator + comparison_term).setResultsName("MainBody")
expr = pp.operatorPrecedence(condition,[
("NOT", 1, pp.opAssoc.RIGHT, ),
("AND", 2, pp.opAssoc.LEFT, ),
("OR", 2, pp.opAssoc.LEFT, ),
])
expression2 = "((Param1 = 1 AND Param2 = 1 ) \
OR (Param3 = 1 AND Param4 = 1)) \
AND \
(((Param5 = 0 AND Param6 = 1 ) \
OR(Param7 = 0 AND Param8 = 1)) \
AND \
((Param9 = 0 AND Param10 = 1 ) \
OR(Param11 = 0 AND Param12 = 1)))"
out = expr.parseString(expression2)
text = out.asXML()
f = open('rules.xml','w+')
f.write(text)
f.close()
root = ET.parse("rules.xml").getroot()
print ET.tostring(root)
将pyparsing导入为pp
将xml.etree.ElementTree作为ET导入
operator=pp.Regex(“>=| |=<=”)(“operator”)
整数=pp.Regex(r“[+-]?\d+(:?\。\d*)?(:?[eE][+-]?\d+)?(:?[eE][+-]?\d+)(“整数”)
参数=pp.Word(pp.alphas,pp.alphanums+“”+“+”-”(“参数”)
比较项=参数|整数
firstExpression=pp.Forward()
secondExpression=pp.Forward()
mainbody=pp.Group(第一个表达式+运算符+第二个表达式)(“mainbody”)
firstExpression这是您的代码,只做了一些更改:
- 将“AND”、“OR”和“NOT”更改为关键字表达式,结果名称为“operator”,以便将它们包装在
标记中
- 为
OperatorRecessence
创建的expr
的内部表达式(最近更名为infixNotation
)创建一个结果名称
- 从parseString返回的单个项列表中提取第0个元素
- 在对asXML的调用中添加最外层的标记名
operator=pp.oneOf(“>=<=”(“operator”)
number=pp.Regex(r“[+-]?\d+(:?\。\d*)?(:?[eE][+-]?\d+)?(:?[eE][+-]?\d+)(“第二个表达式”)
标识符=pp.Word(pp.alphas,pp.alphanums+““+”)(“第一个表达式”)
比较项=标识符|编号
条件=pp.Group(比较项+运算符+比较项)(“主体”)
#使用“运算符”结果名称将AND、OR和NOT定义为关键字
AND=pp.Keyword(“AND”)(“operator”)
或=pp.Keyword(“或”)(“运算符”)
NOT=pp.Keyword(“NOT”)(“operator”)
expr=pp.operator当前(条件[
(不,1,pp.opAssoc.RIGHT,),
(和,2,pp.opAssoc.左),,
(或,2,pp.opAssoc.左),,
])
#将结果名称分配给(expr)的未记录黑客-红旗
expr.expr.resultsName=“组”
expression2=“((Param1=1和Param2=1)\
或(参数3=1和参数4=1))\
及\
((Param5=0,Param6=1)\
或(参数7=0和参数8=1))\
及\
((参数9=0和参数10=1)\
或(参数11=0和参数12=1))”
out=expr.parseString(expression2)[0]#从单个项目列表中提取项目0
text=out.asXML(“表达式”)#为最外层的元素添加标记
打印文本
印刷品:
<expression>
<group>
<group>
<MainBody>
<FirstExpression>Param1</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param2</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
<operator>OR</operator>
<group>
<MainBody>
<FirstExpression>Param3</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param4</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
</group>
<operator>AND</operator>
<group>
<group>
<group>
<MainBody>
<FirstExpression>Param5</FirstExpression>
<Operator>=</Operator>
<SecondExpression>0</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param6</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
<operator>OR</operator>
<group>
<MainBody>
<FirstExpression>Param7</FirstExpression>
<Operator>=</Operator>
<SecondExpression>0</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param8</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
</group>
<operator>AND</operator>
<group>
<group>
<MainBody>
<FirstExpression>Param9</FirstExpression>
<Operator>=</Operator>
<SecondExpression>0</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param10</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
<operator>OR</operator>
<group>
<MainBody>
<FirstExpression>Param11</FirstExpression>
<Operator>=</Operator>
<SecondExpression>0</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param12</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
</group>
</group>
</expression>
参数1
=
1.
及
参数2
=
1.
或
Param3
=
1.
及
Param4
=
1.
及
Param5
=
0
及
Param6
=
1.
或
Param7
=
0
及
参数8
=
1.
及
Param9
=
0
及
参数10
=
1.
或
Param11
=
0
及
参数12
=
1.
因此,就这一点而言,您肯定走在了正确的道路上,但我认为,我们必须将结果名称破解到expr
的内部未记录成员变量中,这是一个危险信号,而且很可能,您很快就会达到使用OperatorRecessence
所能达到的极限
您可能需要实现自己的递归解析器来完全控制所有元素和子元素的命名方式。您甚至可能需要实现自己版本的asXML()
,以控制是否获得中间级别,例如上面显示的
标记。以下是您的代码,只做了一些更改:
- 将“AND”、“OR”和“NOT”更改为关键字表达式,结果名称为“operator”,以便将它们包装在
标记中
- 为
OperatorRecessence
创建的expr
的内部表达式(最近更名为infixNotation
)创建一个结果名称
- 从parseString返回的单个项列表中提取第0个元素
- 在对asXML的调用中添加最外层的标记名
operator=pp.oneOf(“>=<=”(“operator”)
number=pp.Regex(r“[+-]?\d+(:?\。\d*)?(:?[eE][+-]?\d+)?(:?[eE][+-]?\d+)(“第二个表达式”)
标识符=pp.Word(pp.alphas,pp.alphanums+““+”)(“第一个表达式”)
比较项=标识符|编号
条件=pp.Group(比较项+运算符+比较项)(“主体”)
#使用“运算符”结果名称将AND、OR和NOT定义为关键字
AND=pp.Keyword(“AND”)(“operator”)
或=pp.Keyword(“或”)(“运算符”)
NOT=pp.Keyword(“NOT”)(“operator”)
expr=pp.operator当前(条件[
(不,1,pp.opAssoc.RIGHT,),
import pyparsing as pp
operator = pp.oneOf(">= <= != > < =")("operator")
integer = pp.Regex(r"[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?")("integer")
parameter = pp.Word(pp.alphas, pp.alphanums + "_" + "." + "-")("parameter")
comparison_term = parameter | integer
firstExpression = pp.Forward()
secondExpression = pp.Forward()
mainbody = pp.Group(firstExpression + operator + secondExpression)("Mainbody")
firstExpression << pp.Group(parameter | pp.Optional(mainbody))("FirstExpression")
secondExpression << pp.Group(integer | pp.Optional(mainbody))("SecondExpression")
AND_ = pp.Keyword("AND")("operator")
OR_ = pp.Keyword("OR")("operator")
NOT_ = pp.Keyword("NOT")("operator")
expr = pp.operatorPrecedence(mainbody,[
(NOT_, 1, pp.opAssoc.RIGHT, ),
(AND_, 2, pp.opAssoc.LEFT, ),
(OR_, 2, pp.opAssoc.LEFT, ),
])
# undocumented hack to assign a results name to (expr) - RED FLAG
expr.expr.resultsName = "Mainbody"
expression1 = "((Param1 = 1) \
OR (Param2 = 1))"
out = expr.parseString(expression1)[0] # extract item 0 from single-item list
text = out.asXML("Mainbody") # add tag for outermost element
print text
<Mainbody>
<Mainbody>
<FirstExpression>
<parameter>Param1</parameter>
</FirstExpression>
<operator>=</operator>
<SecondExpression>
<integer>1</integer>
</SecondExpression>
</Mainbody>
<operator>OR</operator>
<Mainbody>
<FirstExpression>
<parameter>Param2</parameter>
</FirstExpression>
<operator>=</operator>
<SecondExpression>
<integer>1</integer>
</SecondExpression>
</Mainbody>
</Mainbody>
<Mainbody>
<FirstExpression>
<Mainbody>
<FirstExpression>
<parameter>Param1</parameter>
</FirstExpression>
<operator>=</operator>
<SecondExpression>
<integer>1</integer>
</SecondExpression>
</Mainbody>
</FirstExpression>
<operator>OR</operator>
<SecondExpression>
<Mainbody>
<FirstExpression>
<parameter>Param2</parameter>
</FirstExpression>
<operator>=</operator>
<SecondExpression>
<integer>1</integer>
</SecondExpression>
</Mainbody>
</SecondExpression>
</Mainbody>
operator = pp.oneOf(">= <= != > < =")("Operator")
number = pp.Regex(r"[+-]?\d+(:?\.\d*)?(:?[eE][+-]?\d+)?")("SecondExpression")
identifier = pp.Word(pp.alphas, pp.alphanums + "_" + ".")("FirstExpression")
comparison_term = identifier | number
condition = pp.Group(comparison_term + operator + comparison_term)("MainBody")
# define AND, OR, and NOT as keywords, with "operator" results names
AND_ = pp.Keyword("AND")("operator")
OR_ = pp.Keyword("OR")("operator")
NOT_ = pp.Keyword("NOT")("operator")
expr = pp.operatorPrecedence(condition,[
(NOT_, 1, pp.opAssoc.RIGHT, ),
(AND_, 2, pp.opAssoc.LEFT, ),
(OR_, 2, pp.opAssoc.LEFT, ),
])
# undocumented hack to assign a results name to (expr) - RED FLAG
expr.expr.resultsName = "group"
expression2 = "((Param1 = 1 AND Param2 = 1 ) \
OR (Param3 = 1 AND Param4 = 1)) \
AND \
(((Param5 = 0 AND Param6 = 1 ) \
OR(Param7 = 0 AND Param8 = 1)) \
AND \
((Param9 = 0 AND Param10 = 1 ) \
OR(Param11 = 0 AND Param12 = 1)))"
out = expr.parseString(expression2)[0] # extract item 0 from single-item list
text = out.asXML("expression") # add tag for outermost element
print text
<expression>
<group>
<group>
<MainBody>
<FirstExpression>Param1</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param2</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
<operator>OR</operator>
<group>
<MainBody>
<FirstExpression>Param3</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param4</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
</group>
<operator>AND</operator>
<group>
<group>
<group>
<MainBody>
<FirstExpression>Param5</FirstExpression>
<Operator>=</Operator>
<SecondExpression>0</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param6</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
<operator>OR</operator>
<group>
<MainBody>
<FirstExpression>Param7</FirstExpression>
<Operator>=</Operator>
<SecondExpression>0</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param8</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
</group>
<operator>AND</operator>
<group>
<group>
<MainBody>
<FirstExpression>Param9</FirstExpression>
<Operator>=</Operator>
<SecondExpression>0</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param10</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
<operator>OR</operator>
<group>
<MainBody>
<FirstExpression>Param11</FirstExpression>
<Operator>=</Operator>
<SecondExpression>0</SecondExpression>
</MainBody>
<operator>AND</operator>
<MainBody>
<FirstExpression>Param12</FirstExpression>
<Operator>=</Operator>
<SecondExpression>1</SecondExpression>
</MainBody>
</group>
</group>
</group>
</expression>