解析 yaml 文件时出错:发现无法启动任何标记的字符“%”
Error when parsing yaml file : found character '%' that cannot start any token
我正在尝试从具有类似于 jinaj2 模板语法的一些表达式的 yaml 文件中解析数据,目标是删除或向文件添加一些项目。
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)
执行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)
在 YAML 中,“{”开始一个流式映射,因此 (%
) 将成为该映射的第一个键的开始,并且该字符不允许作为第一个字符。
通常您会先处理文件的模板,然后再应用 YAML。您无法轻易逆转该过程,因为 list 的值必须是有效的 YAML 构造。
使其可解析的解决方案之一是将 list
的值更改为有效的 YAML,例如:
list:
- {% for elt in customer %}
- code: {{ elt.code }}
name: {{ elt.name }}
country: {{ elt.country }}
- {% endfor %}
或:
list: |
{% for elt in customer %}
- code: {{ elt.code }}
name: {{ elt.name }}
country: {{ elt.country }}
{% endfor %}
这将不再使它成为可模板化的 bij jinja2。
您可以从 {%
更改 jinja2 中的启动顺序,但这对您没有帮助(即您仍然无法获得有效的 YAML)。我目前看到的唯一真正的解决方案是完全放弃 jinja2 并使用 Python 中的对象列表(在访问时扩展)实现 for
循环。
如果允许在应用jinja2之前总是进行预处理,您可以将文件更改为:
AddCodesList:
body:
list:
# {% for elt in customer %}
- code: '{{ elt.code }}'
name: '{{ elt.name }}'
country: '{{ elt.country }}'
# {% endfor %}
因为它会加载,但您可能需要在 运行 模板引擎之前将 # b{
更改为 {
。
引用 单引号 因为只有单引号具有特殊含义。使用双引号,您更经常会得到 pre-processor 插入的内容,这会使 YAML 不正确(例如 DOS/Windows 样式 full-file-paths:'C:\yaml\abc.yaml'
是正确的,但 "c:\yaml\abc.yaml"
将在 YAML 解析期间给你一个错误。
问题已通过以下结构解决:
AddCodesList:
body:
list:
# {% for elt in customer %}
- code: "{{ elt.code }}"
name: "{{ elt.name }}"
country: "{{ elt.country }}"
# {% endfor %}
我正在尝试从具有类似于 jinaj2 模板语法的一些表达式的 yaml 文件中解析数据,目标是删除或向文件添加一些项目。
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)
执行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)
在 YAML 中,“{”开始一个流式映射,因此 (%
) 将成为该映射的第一个键的开始,并且该字符不允许作为第一个字符。
通常您会先处理文件的模板,然后再应用 YAML。您无法轻易逆转该过程,因为 list 的值必须是有效的 YAML 构造。
使其可解析的解决方案之一是将 list
的值更改为有效的 YAML,例如:
list:
- {% for elt in customer %}
- code: {{ elt.code }}
name: {{ elt.name }}
country: {{ elt.country }}
- {% endfor %}
或:
list: |
{% for elt in customer %}
- code: {{ elt.code }}
name: {{ elt.name }}
country: {{ elt.country }}
{% endfor %}
这将不再使它成为可模板化的 bij jinja2。
您可以从 {%
更改 jinja2 中的启动顺序,但这对您没有帮助(即您仍然无法获得有效的 YAML)。我目前看到的唯一真正的解决方案是完全放弃 jinja2 并使用 Python 中的对象列表(在访问时扩展)实现 for
循环。
如果允许在应用jinja2之前总是进行预处理,您可以将文件更改为:
AddCodesList:
body:
list:
# {% for elt in customer %}
- code: '{{ elt.code }}'
name: '{{ elt.name }}'
country: '{{ elt.country }}'
# {% endfor %}
因为它会加载,但您可能需要在 运行 模板引擎之前将 # b{
更改为 {
。
引用 单引号 因为只有单引号具有特殊含义。使用双引号,您更经常会得到 pre-processor 插入的内容,这会使 YAML 不正确(例如 DOS/Windows 样式 full-file-paths:'C:\yaml\abc.yaml'
是正确的,但 "c:\yaml\abc.yaml"
将在 YAML 解析期间给你一个错误。
问题已通过以下结构解决:
AddCodesList:
body:
list:
# {% for elt in customer %}
- code: "{{ elt.code }}"
name: "{{ elt.name }}"
country: "{{ elt.country }}"
# {% endfor %}