我想使用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的已知错误吗? 有什么补丁/解决方法?
答案 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()))