python - 使用 get_template jinja2 生成动态 XML 模板

标签 python xml jinja2

我是 Python 和 XML 新手,我使用下面的 python 代码和 xml 文件来替换 xml 文件中变量的值,并生成另一个输出 xml 文件,其中参数 {{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 个元素的列表:

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 和*可选以及相应的 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 - 使用 get_template jinja2 生成动态 XML 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38432809/

相关文章:

java - 如何从 WebView 下载图像

java - 从 xml 列表中获取平均值

django - 如果来自 view.py 的两个值相等,则禁用按钮

python - 如何正确导入jinja2.ext.loopcontrols到Flask?

python - 尝试更改 RTSP 视频流的分辨率

python - 如何使用 theano 重现 scipy.convolve

python - 如何播放随机 WAV。来自 Python 文件夹的示例?

python - 密谋:如何反转轴?

xml - xslt中如何获取同一节点下的最大值

python - CherryPy 无法正确处理 Jinja2 模板中的非 ASCII 字符