Próbuję przeanalizować dane z pliku YAML o niektórych wyrażeniach podobnych do składni szablonu Jinaj2, celem jest usunięcie lub dodanie elementów do pliku.

addcodeslist.yaml

AddCodesList:
  body:
    list:
    {% for elt in customer %}
      - code: {{ elt.code }}
        name: {{ elt.name }}
        country: {{ elt.country }}
    {% endfor %}   
  result:
    json:
      responseCode: {{ responseCode }}
      responseMsg: {{ responseMsg }}
      responseData: {{ responseData }}

parsefile.py

import ruamel.yaml
from ruamel.yaml.util import load_yaml_guess_indent

data,indent,block_seq_indent=load_yaml_guess_indent(open('AddCodesList.yaml'), preserve_quotes=True)

#delete item
del data['body']['list']['code']
#add new item
data['parameters'].insert(2, 'ssl_password','xxxxxx')#create new file
ruamel.yaml.round_trip_dump(data, open('missingCode.yaml', 'w'), explicit_start=True)

Mam następujący błąd podczas wykonywania skryptu parsefile.py:

    Traceback (most recent call last):
      File "d:/workspace/TEST/manageItem.py", line 4, in <module>
        data, indent, block_seq_indent = load_yaml_guess_indent(open('AddCodesList.
...
        if self.check_token(ValueToken):
      File "C:\Python34\lib\site-packages\ruamel\yaml\scanner.py", line 1534, in ch
        self.fetch_more_tokens()
      File "C:\Python34\lib\site-packages\ruamel\yaml\scanner.py", line 269, in fet
        % utf8(ch), self.get_mark())
    ruamel.yaml.scanner.ScannerError: while scanning for the next token
    found character '%' that cannot start any token
      in "<unicode string>", line 4, column 6:
            {% for elt in customer %}
             ^ (line: 4)
7
bcharfi 16 luty 2017, 12:27

2 odpowiedzi

Najlepsza odpowiedź

Problem został rozwiązany z następującą strukturą:

AddCodesList:
  body:
    list:
    # {% for elt in customer %}
      - code: "{{ elt.code }}"
        name: "{{ elt.name }}"
        country: "{{ elt.country }}"
    # {% endfor %}  
1
bcharfi 16 luty 2017, 16:04

W YAML "{" rozpoczyna mapowanie stylu przepływu, więc ({x0}}) będzie początkiem pierwszego klucza tego mapowania, a postać nie jest dozwolona jako pierwszy znak.

Zwykle przetwarzasz najpierw szablony pliku, a następnie zastosować YAML. Nie można łatwo odwrócić ten proces, ponieważ wartość listy musiałaby być ważnym konstruktem YAML.

Jednym z rozwiązań, które należy przenikać, jest zmiana wartości dla list, aby poprawić jaml jak:

list:
  - {% for elt in customer %}
  - code: {{ elt.code }}
    name: {{ elt.name }}
    country: {{ elt.country }}
  - {% endfor %} 

Lub:

list: |
    {% for elt in customer %}
      - code: {{ elt.code }}
        name: {{ elt.name }}
        country: {{ elt.country }}
    {% endfor %} 

I to już nie sprawi, że jest to prostowane bij jinja2.

Możesz zmienić sekwencję startu w Jinja2 z {X0}}, ale ten kosi roboczych nie pomagają Ci (tj. Nadal nie otrzymasz prawidłowego YAML). Jedynym prawdziwym rozwiązaniem, które widzę w tej chwili, jest całkowicie upuścić Jinja2 i wdrożenie pętli for za pomocą listy jak obiekt w Pythonie (który zostanie rozszerzony w dostępie).

Jeśli jest to dopuszczenie zawsze przed zastosowaniem Jinja2, możesz zmienić plik do:

AddCodesList:
  body:
    list:
    # {% for elt in customer %}
      - code: '{{ elt.code }}'
        name: '{{ elt.name }}'
        country: '{{ elt.country }}'
    # {% endfor %}   

Jak to się załaduje, ale może być konieczne zmianę # b{ do po prostu { przed uruchomieniem silnika szablonu.

Cytat z pojedynczych cytatów jak między tymi jedynymi pojedynczym cytatem ma szczególne znaczenie. Dzięki podwójnym cytatom częściej dostaniesz coś włożonego przez pre-procesora, który sprawia, że rzeczy nieprawidłowe YAML (np. Dos / Windows Style Pełne ścieżki: 'C:\yaml\abc.yaml' jest poprawne, ale "c:\yaml\abc.yaml" da Ci błąd podczas parsowania Yamla.

1
Anthon 31 sierpień 2017, 15:17