2014-12-31 119 views
4

我最近開始使用YAML和jinja2。我無法理解爲什麼我需要在jinja2模板中引用我的YAML映射的整個結構。訪問與jinja2的嵌套YAML映射

我有以下YAML文件

--- 
PROVIDERS: 
    PROV1: 
     int: ge-0/1/1 
     ipv4: 10.0.1.1/30 
    PROV2: 
     int: ge-0/1/2 
     ipv4: 10.0.1.2/30 

,這是我的Jinja2模板

{%- for provider in PROVIDERS %} 
    {{ provider }} 
    {{ PROVIDERS[provider].int }} <-- why not provider.int 
    {{ PROVIDERS[provider].ipv4 }} <-- why not provider.ipv4 
{%- endfor %} 

與pyyaml解析給我的(預期)輸出

PROV2 
ge-0/1/2 
10.0.1.2/30 
PROV1 
ge-0/1/1 
10.0.1.1/30 

但是爲什麼一定要我用PROVIDERS[provider].intprovider.int不起作用。

此外,我在想,如果我能做出這樣的映射,而不是一個嵌套映射列表:

--- 
PROVIDERS: 
    - PROV1: 
     int: ge-0/1/1 
     ipv4: 10.0.1.1/30 
    - PROV2: 
     int: ge-0/1/2 
     ipv4: 10.0.1.2/30 

我已經試過這樣做,但Jinja2的模板不再生產所需的輸出。

回答

4

這裏要考慮兩件事情:

  1. 什麼Python數據結構是從你的YAML文件構建?
  2. 你的模板如何引用數據結構的元素?

接聽1點很簡單:

>>> import yaml 
>>> from pprint import pprint 
>>> p1 = yaml.load(""" 
... --- 
... PROVIDERS: 
...  PROV1: 
...   int: ge-0/1/1 
...   ipv4: 10.0.1.1/30 
...  PROV2: 
...   int: ge-0/1/2 
...   ipv4: 10.0.1.2/30 
... """) 
>>> pprint(p1) 
{'PROVIDERS': {'PROV1': {'int': 'ge-0/1/1', 'ipv4': '10.0.1.1/30'}, 
       'PROV2': {'int': 'ge-0/1/2', 'ipv4': '10.0.1.2/30'}}} 

你有一個單一的項目,其關鍵是'PROVIDERS',其值與鍵'PROV1''PROV2',其每個值是一個字典詞典另一本字典。這是一個比你需要的結構更深的嵌套結構(稍後會有更多內容),但現在我們可以看到你的數據結構,我們可以計算出你的模板發生了什麼。

這條線:

{%- for provider in PROVIDERS %} 

迭代的PROVIDERS(其中,由於你的輸出,顯然是該第二級嵌套詞典這是在頂層用於密鑰'PROVIDERS'值字典)。既然你遍歷的關鍵是什麼,你那麼就需要使用這些密鑰來獲得在相關的值:

{{ PROVIDERS[provider].int }} 
{{ PROVIDERS[provider].ipv4 }} 

你的目的更直接YAML文件將是這樣的:

--- 
- id: PROV1 
    int: ge-0/1/1 
    ipv4: 10.0.1.1/30 
- id: PROV2 
    int: ge-0/1/2 
    ipv4: 10.0.1.2/30 

請注意,我們放棄了冗餘單項映射,並將映射的第二級映射替換爲映射列表。同樣,我們可以檢查:

>>> p2 = yaml.load(""" 
... --- 
... - id: PROV1 
... int: ge-0/1/1 
... ipv4: 10.0.1.1/30 
... - id: PROV2 
... int: ge-0/1/2 
... ipv4: 10.0.1.2/30 
... """) 
>>> pprint(p2) 
[{'int': 'ge-0/1/1', 'ipv4': '10.0.1.1/30', 'id': 'PROV1'}, 
{'int': 'ge-0/1/2', 'ipv4': '10.0.1.2/30', 'id': 'PROV2'}] 

這裏是您的範本如何使用這些數據結構:

{%- for provider in PROVIDERS %} 
    {{ provider.id }} 
    {{ provider.int }} 
    {{ provider.ipv4 }} 
{%- endfor %} 

顯然,你將需要修改其提供PROVIDERS到模板的代碼,因爲它是現在由整個YAML文檔表示的頂級列表,而不是嵌套在其中的字典。