使用setResultsName()和asXML()进行PyParsing时标记错误

时间:2015-11-10 01:42:39

标签: xml pyparsing

我想使用PyParsing来解析文本并输出为XML(asXML())。但XML输出中的标记与setResultsName不一致。

请参阅以下代码段:

p1 = (Literal('a').setResultsName('tag_a')).setResultsName('tag_out')
print(p1.parseString('a').asXML())
# Output:
# <tag_out>
#   <tag_out>a</tag_out>
# </tag_out>

p2 = (Literal('a').setResultsName('tag_a') +
      Literal('b').setResultsName('tag_b')).setResultsName('tag_out')
print((p2.parseString('a b').asXML()))

# The result is randomly chosen from these two outputs.
# <tag_out>
#   <tag_a>a</tag_a>
#   <tag_b>b</tag_b>
# </tag_out>
#
# <tag_out>
#   <tag_out>a</tag_out>
#   <tag_b>b</tag_b>
# </tag_out>

请注意,第一个内部元素的标记通常是错误的。

这是PyParsing的已知错误吗? 有什么补丁/解决方法?

1 个答案:

答案 0 :(得分:0)

Pyparsing不会根据您的代码自动为您的语法中的表达式赋予结构。这是设计使得部分表达式可以很容易地合并在一起,因此:

grammar = exprA + exprB + exprC

grammar = exprA + (exprB + exprC)

tmp = exprA + exprB
grammar = tmp + exprC

表现方式相同。所以只是在表达式周围放置()并不会自动定义你的语法的另一个级别。

Pyparsing为您想要的内容提供Group类。如果将代码更改为:

,您的结果将大大改善
p1 = Group(Literal('a').setResultsName('tag_a')).setResultsName('tag_out')
print(p1.parseString('a').asXML())

p2 = Group(Literal('a').setResultsName('tag_a') +
      Literal('b').setResultsName('tag_b')).setResultsName('tag_out')
print((p2.parseString('a b').asXML()))

话虽如此,asXML()并不是pyparsing的最大部分,因为它必须在某些情况下在走一个结构并创建输出标签时进行猜测。如果这仅用于调试目的,我建议改为使用dump()方法。

我还建议你切换到setResultsName的隐式可调用形式 - 我认为它简化了你的语法代码而不会损害可读性。看到差异:

p1 = Group(Literal('a')('tag_a'))('tag_out')
print(p1.parseString('a').asXML())

p2 = Group(Literal('a')('tag_a') + Literal('b')('tag_b'))('tag_out')
print((p2.parseString('a b').asXML()))