python - 使用 Python TTP 解析文本以更正 json
问题描述
假设我有以下文字:
interface GigabitEthernet1/0/1.1
qinq stacking vid 10 pe-vid 100
qinq stacking vid 20 pe-vid 100
qinq stacking vid 30 pe-vid 200
#
interface GigabitEthernet1/0/2.1
qinq stacking vid 20 pe-vid 200
#
我想使用Template Text Parser解析它。
这是我想要得到的目标 JSON:
[
{
"subinterfaces": [
{
"interface": "GigabitEthernet1/0/1.1",
"stacking": {
"100": [ "10", "20" ],
"200": [ "30" ]
}
},
{
"interface": "GigabitEthernet1/0/2.1",
"stacking": {
"200": [ "20" ]
}
}
]
}
]
我试过这个模板
<group name="subinterfaces">
interface {{ interface | contains('.') }}
<group name="stacking.{{ pevid }}">
qinq stacking vid {{ vid }} pe-vid {{ pevid }}
</group>
# {{ _end_ }}
</group>
但它给了我
[
{
"subinterfaces": [
{
"interface": "GigabitEthernet1/0/1.1",
"stacking": {
"100": [
{
"vid": "10"
},
{
"vid": "20"
}
],
"200": {
"vid": "30"
}
}
},
{
"interface": "GigabitEthernet1/0/2.1",
"stacking": {
"200": {
"vid": "20"
}
}
}
]
}
]
使用“|”应用于vid的任何修饰符/函数 (管)没有任何作用。
这个问题背后的动机是学习 TTP 机制。请不要使用其他工具发送答案。
解决方案
这是一个有趣的问题,但是不存在匹配变量或组函数来满足在列表中组合匹配项同时{{ match }}
在一行上定义多个变量的要求。存在joinmatches功能,但由于特定原因,它在这里不起作用。
我能想到的最好的结果是使用 Python 进行结果后处理。
例如,此模板post_processing
使用宏标签定义 Python 函数,并使用输出标签通过它传递结果:
<group name="subinterfaces">
interface {{ interface | contains('.') }}
<group name="stacking.{{ pevid }}.{{ vid }}">
qinq stacking vid {{ vid }} pe-vid {{ pevid }}
</group>
# {{ _end_ }}
</group>
<output macro="post_process"/>
<macro>
def post_process(data):
for item in data[0]["subinterfaces"]:
item["stacking"] = {
k: list(v.keys()) for k, v in item["stacking"].items()
}
return(data)
</macro>
subinterfaces
组被修改以产生这些结果:
[
[
{
"subinterfaces": [
{
"interface": "GigabitEthernet1/0/1.1",
"stacking": {
"100": {
"10": {},
"20": {}
},
"200": {
"30": {}
}
}
},
{
"interface": "GigabitEthernet1/0/2.1",
"stacking": {
"200": {
"20": {}
}
}
}
]
}
]
]
在使用宏通过输出器传递上述数据后post_processing
,结果转换为所需的结构:
[
[
{
"subinterfaces": [
{
"interface": "GigabitEthernet1/0/1.1",
"stacking": {
"100": [
"10",
"20"
],
"200": [
"30"
]
}
},
{
"interface": "GigabitEthernet1/0/2.1",
"stacking": {
"200": [
"20"
]
}
}
]
}
]
]