【问题标题】:Jackson YAML Parser Deleted Special charactersJackson YAML Parser 删除了特殊字符
【发布时间】:2020-05-13 21:04:33
【问题描述】:

我在使用带有 YAMLFactory 的 ObjectMapper 解析 YAML 文件时遇到问题

  1. 我尝试解析的 YAML 文件:https://drive.google.com/open?id=1Q85OmjH-IAIkordikLTsC1oQVTg8ggc8
  2. 使用 readValue 解析文件,如下所示:

    ObjectMapper mapper = new ObjectMapper(new YAMLFactory().enable(Feature.MINIMIZE_QUOTES)// .disable(Feature.WRITE_DOC_START_MARKER)// .disable(YAMLGenerator.Feature.SPLIT_LINES)); TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() {}; HashMap<String, Object> obj = mapper.readValue(responseBuffer.toString(), typeRef);

  3. 通过以下方式将 Obj 转换为 json 然后再次转换为 YAML:

    JsonElement jsonElem = wrapJacksonObject(obj); String cloudTemplateJsonString = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting()// .create()// .toJson(jsonElem); JsonNode jsonNode = mapper.readTree(cloudTemplateJsonString); String yaml = new YAMLMapper().enable(Feature.MINIMIZE_QUOTES)// .disable(Feature.WRITE_DOC_START_MARKER)// .writeValueAsString(jsonNode);

  4. 检查最后一个字符串后,我看到这些特殊字符已更改/删除(它们在第 2 点之后完全更改):

    一个。 ' 转移到 ' 或 已删除 湾。 ! :关于感叹号:它之后的整个字符串直到第一个空格被完全删除

    例子:

    Version: !Join ['-', [!Ref GatewayVersion, GW]]
    After Parsing  
    Version:
       - '-'
       - - GatewayVersion
       - GW
    

单引号有时也会被删除/转换为双引号

 AllowedPattern: '^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})$'

解析单引号后删除:

 AllowedPattern: ^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})$
  1. 我尝试通过自定义 CharacterEscapes 类的实现来使用转义字符自定义,但没有帮助

【问题讨论】:

  • 调试后,我发现问题与:Object value = deserialize(p, ctxt); Inside Class : UntypedObjectDeserializer 在反序列化尝试查找值时,我看到 Parser 具有当前令牌:!Ref 但 YAMLParser 先进到下一个令牌并以一种奇怪的方式忽略它我正在谈论这一行 Number 648 JsonToken t = p.nextToken();在反序列化函数中,我需要一位使用 YamlParser 的专家来找出问题所在

标签: jackson yaml


【解决方案1】:

在 YAML 中,诸如字符串文字之类的值可以由表示节点元数据(称为节点属性)的标记前置。以 bang ! 开头的标记被认为是“节点标签”,以 & 符号开头的标记 &amp; 是“节点锚点”。

https://yaml.org/spec/1.2/spec.html#id2783797

JSON 没有等效的功能。由于 Jackson 主要是一个 JSON 解析库,其结构化数据节点的内部表示没有元数据字段,因此它的 YAMLFactory 解析器实现简单地丢弃了它们。

查看您的 YAML 文件,我希望文件的预期解析器(aws 的 cloudwatch cli 工具?)会知道如何使用这些 !Join 和 !Ref 节点标签来构建 Version 字段的内部表示。

类似地,文本值周围的单引号或双引号被认为是标记的一部分(即,使用了解析器)而不是值的一部分。因此解析器会丢弃这些字符(在使用它们作为如何使用值的指南之后)。将内部表示重新序列化回 YAML 或 JSON 时,可以添加或不添加引号(双引号或单引号)。

【讨论】:

    猜你喜欢
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    相关资源
    最近更新 更多