使用 get_template jinja2 动态 XML 模板生成
Dynamic XML template generation using get_template jinja2
我是 Python 和 XML 中的新手,我正在使用下面的 python 代码和 xml 文件来替换 [=中的变量值=43=] 文件并在参数 {{param}}
.
中生成另一个具有更新值的输出 xml 文件
netconf_payload.py
#!/usr/bin/env python
import os
from jinja2 import Environment, FileSystemLoader
PATH = os.path.dirname(os.path.abspath(__file__))
TEMPLATE_ENVIRONMENT = Environment(
autoescape=False,
loader=FileSystemLoader(os.path.join(PATH, 'templates')),
trim_blocks=False)
def render_template(template_filename, context):
return TEMPLATE_ENVIRONMENT.get_template(template_filename).render(context)
def create_index_html():
fname = "bridge.xml"
param = [3, 'ieee', 3]
context = {
'param': param
}
#
with open(fname, 'w') as f:
html = render_template('bridge.xml', context)
f.write(html)
def main():
create_index_html()
if __name__ == "__main__":
main()
templates/bridge.xml
<vr>
<vrId>0</vrId>
<bridge>
{% set counter = 0 -%}
{% for param in param -%}
<bridgeId>{{ param }}</bridgeId>
<bridgeType>{{ param }}</bridgeType>
<bridgeId>{{ param }}</bridgeId>
{% set counter = counter + 1 -%}
{% endfor -%}
</bridge>
</vr>
现在执行命令:python netconf_payload.py
它将生成如下输出 bridge.xml 文件:
<vr>
<vrId>0</vrId>
<bridge>
<bridgeId>3</bridgeId>
<bridgeType>3</bridgeType>
<bridgeId>3</bridgeId>
<bridgeId>ieee</bridgeId>
<bridgeType>ieee</bridgeType>
<bridgeId>ieee</bridgeId>
<bridgeId>3</bridgeId>
<bridgeType>3</bridgeType>
<bridgeId>3</bridgeId>
</bridge>
</vr>
我想要的预期输出是:
<vr>
<vrId>0</vrId>
<bridge>
<bridgeId>3</bridgeId>
<bridgeType>ieee</bridgeType>
<bridgeId>3</bridgeId>
</bridge>
</vr>
那么 param
是一个总是有 3 个值的列表吗?我不认为你想在这种情况下迭代它,我认为你需要明确引用列表中的每个项目以获得你想要的输出。例如
<bridge>
<bridgeId>{{ param[0] }}</bridgeId>
<bridgeType>{{ param[1] }}</bridgeType>
<bridgeId>{{ param[2] }}</bridgeId>
</bridge>
您正在遍历 param
,这是一个包含 3 个元素的列表:
param = [3, 'ieee', 3]
对于这些值中的每一个,您创建 3 个元素:
{% for param in param -%}
<bridgeId>{{ param }}</bridgeId>
<bridgeType>{{ param }}</bridgeType>
<bridgeId>{{ param }}</bridgeId>
{% endfor -%}
所以你的输出完全符合预期。
完全删除循环,将 3 个元素插入 3 个单独的标签中:
<vr>
<vrId>0</vrId>
<bridge>
<bridgeId>{{ param[0] }}</bridgeId>
<bridgeType>{{ param[1] }}</bridgeType>
<bridgeId>{{ param[2] }}</bridgeId>
</bridge>
</vr>
您可能想要使用 字典 来代替,因为这样您就可以命名 3 个元素:
param = {'id1': 3, 'type': 'ieee', 'id2': 3}
和
<vr>
<vrId>0</vrId>
<bridge>
<bridgeId>{{ param.id1 }}</bridgeId>
<bridgeType>{{ param.type }}</bridgeType>
<bridgeId>{{ param.id2 }}</bridgeId>
</bridge>
</vr>
或者如果您需要生成多个 bridgeId
和 *optional 以及相应的 bridgeType
标签,也许您需要一个 字典列表 :
param = [{'id1': 3, 'type': 'ieee'}, {'id2': 3}]
请注意,第二个字典在这里没有 'type'
键。渲染则变为:
<vr>
<vrId>0</vrId>
<bridge>
{% for entry in param -%}
<bridgeId>{{ entry.id }}</bridgeId>
{% if entry.type %}<bridgeType>{{ entry.type }}</bridgeType>{% endif %}
{% endfor -%}
</bridge>
</vr>
我是 Python 和 XML 中的新手,我正在使用下面的 python 代码和 xml 文件来替换 [=中的变量值=43=] 文件并在参数 {{param}}
.
netconf_payload.py
#!/usr/bin/env python
import os
from jinja2 import Environment, FileSystemLoader
PATH = os.path.dirname(os.path.abspath(__file__))
TEMPLATE_ENVIRONMENT = Environment(
autoescape=False,
loader=FileSystemLoader(os.path.join(PATH, 'templates')),
trim_blocks=False)
def render_template(template_filename, context):
return TEMPLATE_ENVIRONMENT.get_template(template_filename).render(context)
def create_index_html():
fname = "bridge.xml"
param = [3, 'ieee', 3]
context = {
'param': param
}
#
with open(fname, 'w') as f:
html = render_template('bridge.xml', context)
f.write(html)
def main():
create_index_html()
if __name__ == "__main__":
main()
templates/bridge.xml
<vr>
<vrId>0</vrId>
<bridge>
{% set counter = 0 -%}
{% for param in param -%}
<bridgeId>{{ param }}</bridgeId>
<bridgeType>{{ param }}</bridgeType>
<bridgeId>{{ param }}</bridgeId>
{% set counter = counter + 1 -%}
{% endfor -%}
</bridge>
</vr>
现在执行命令:python netconf_payload.py 它将生成如下输出 bridge.xml 文件:
<vr>
<vrId>0</vrId>
<bridge>
<bridgeId>3</bridgeId>
<bridgeType>3</bridgeType>
<bridgeId>3</bridgeId>
<bridgeId>ieee</bridgeId>
<bridgeType>ieee</bridgeType>
<bridgeId>ieee</bridgeId>
<bridgeId>3</bridgeId>
<bridgeType>3</bridgeType>
<bridgeId>3</bridgeId>
</bridge>
</vr>
我想要的预期输出是:
<vr>
<vrId>0</vrId>
<bridge>
<bridgeId>3</bridgeId>
<bridgeType>ieee</bridgeType>
<bridgeId>3</bridgeId>
</bridge>
</vr>
那么 param
是一个总是有 3 个值的列表吗?我不认为你想在这种情况下迭代它,我认为你需要明确引用列表中的每个项目以获得你想要的输出。例如
<bridge>
<bridgeId>{{ param[0] }}</bridgeId>
<bridgeType>{{ param[1] }}</bridgeType>
<bridgeId>{{ param[2] }}</bridgeId>
</bridge>
您正在遍历 param
,这是一个包含 3 个元素的列表:
param = [3, 'ieee', 3]
对于这些值中的每一个,您创建 3 个元素:
{% for param in param -%}
<bridgeId>{{ param }}</bridgeId>
<bridgeType>{{ param }}</bridgeType>
<bridgeId>{{ param }}</bridgeId>
{% endfor -%}
所以你的输出完全符合预期。
完全删除循环,将 3 个元素插入 3 个单独的标签中:
<vr>
<vrId>0</vrId>
<bridge>
<bridgeId>{{ param[0] }}</bridgeId>
<bridgeType>{{ param[1] }}</bridgeType>
<bridgeId>{{ param[2] }}</bridgeId>
</bridge>
</vr>
您可能想要使用 字典 来代替,因为这样您就可以命名 3 个元素:
param = {'id1': 3, 'type': 'ieee', 'id2': 3}
和
<vr>
<vrId>0</vrId>
<bridge>
<bridgeId>{{ param.id1 }}</bridgeId>
<bridgeType>{{ param.type }}</bridgeType>
<bridgeId>{{ param.id2 }}</bridgeId>
</bridge>
</vr>
或者如果您需要生成多个 bridgeId
和 *optional 以及相应的 bridgeType
标签,也许您需要一个 字典列表 :
param = [{'id1': 3, 'type': 'ieee'}, {'id2': 3}]
请注意,第二个字典在这里没有 'type'
键。渲染则变为:
<vr>
<vrId>0</vrId>
<bridge>
{% for entry in param -%}
<bridgeId>{{ entry.id }}</bridgeId>
{% if entry.type %}<bridgeType>{{ entry.type }}</bridgeType>{% endif %}
{% endfor -%}
</bridge>
</vr>