【问题标题】:What is a complex mapping key in YAML?YAML 中的复杂映射键是什么?
【发布时间】:2016-03-03 10:08:39
【问题描述】:

在 YAML specs 上有一段关于问号的 2.11 段:

问号和空格(“?”)表示复杂的映射键。在块集合中,键:值对可以紧跟在破折号、冒号或问号之后。

给出这个例子:

---
? - Detroit Tigers
  - Chicago cubs
:
  - 2001-07-23

这个其他例子也无法转换为 XML:

%YAML 1.2
- - -
!!map {
  ? !!str "Not indented"
  : !!map {
      ? !!str "By one space"
      : !!str "By four\n  spaces\n",
      ? !!str "Flow style"
      : !!seq [
          !!str "By two",
          !!str "Also by two",
          !!str "Still by two",
        ]
    }
}

很遗憾,我不明白这是什么意思。我尝试使用codebeautify 将其转换为 XML,但出现错误。

所以我的问题是:

问号有什么作用?

【问题讨论】:

    标签: yaml


    【解决方案1】:

    规范不是很清楚,但经过一番摸索后,我想通了。 YAML 有两种块映射键:隐式和显式。隐式风格是你熟悉的那种:

    mapping:
      foo: 1
      bar baz: 2
      "qux:quux": 3
    

    如果我们在 Ruby 中加载这个 YAML(例如),我们会得到以下结果:

    { "mapping" =>
      { "foo"      => 1,
        "bar baz"  => 2,
        "qux:quux" => 3
      }
    }
    

    但我们也可以使用显式风格来表达同样的事情:

    mapping:
      ? foo
      : 1
      ? bar baz
      : 2
      ? "qux:quux"
      : 3
    

    换句话说,以? 开头的行表示一个键,而以: 开头的行表示一个值。

    那有什么用?好吧,它让我们可以使用任何 YAML 结构作为映射键。想要使用序列作为映射键?你可以!想要使用映射作为映射键?看:

    mapping:
      # Use a sequence as a key
      ? - foo
        - bar
      : 1
    
      # Use a mapping as a key
      ? baz: qux
      : 2
    
      # You can skip the value, which implies `null`
      ? quux
    
      # You can leave the key blank, which implies a `null` key
      ?
      : 3
    
      # You can even skip both the key and value, so both will be `null`
      ?
    
      # Or you can use a preposterously long scalar as a key
      ? |
        We the People of the United States, in Order to form a more
        perfect Union, establish Justice, insure domestic Tranquility,
        provide for the common defence, promote the general Welfare,
        and secure the Blessings of Liberty to ourselves and our
        Posterity, do ordain and establish this Constitution for the
        United States of America.
      : 3
    
      # Or just be ridiculous
      ? - foo: bar
          baz:
          - { qux: quux }
        - stahp
      : 4
    

    在 Ruby 中,这将产生以下令人愉快的哈希:

    { "mapping" =>
      { [ "foo", "bar" ]   => 1,
        { "baz" => "qux" } => 2,
        "quux"             => nil,
        nil                => nil,
        "We the People of the United States, in Order to form a more\nperfect Union, establish Justice, insure domestic Tranquility,\nprovide for the common defence, promote the general Welfare,\nand secure the Blessings of Liberty to ourselves and our\nPosterity, do ordain and establish this Constitution for the\nUnited States of America.\n" => 3
        [ { "foo" => "bar", "baz" => [ { "qux" => "quux" } ] }, "stahp" ] => 4
      }
    }
    

    哦,“底特律猛虎队”示例在 Ruby 解析时看起来像这样:

    YAML.load <<YML
    ? - Detroit Tigers
      - Chicago cubs
    :
      - 2001-07-23
    
    ? [ New York Yankees,
        Atlanta Braves ]
    : [ 2001-07-02, 2001-08-12,
        2001-08-14 ]
    YML
    # => { [ "Detroit Tigers", "Chicago cubs" ] =>
    #          [ #<Date: 2001-07-23 ((2452114j,0s,0n),+0s,2299161j)> ],
    #      [ "New York Yankees", "Atlanta Braves" ] =>
    #          [ #<Date: 2001-07-02 ((2452093j,0s,0n),+0s,2299161j)>,
    #            #<Date: 2001-08-12 ((2452134j,0s,0n),+0s,2299161j)>,
    #            #<Date: 2001-08-14 ((2452136j,0s,0n),+0s,2299161j)> ]
    #     }
    

    【讨论】:

    • 很好的答案,这是对规范中鲜为人知的元素的很好参考。
    【解决方案2】:

    只是想补充一下,如果您的键是 特殊字符,那么复杂的映射也会有所帮助。例如,如果您的 k:v 是:

    !: "abc"
    

    不允许使用这种特殊的字符键 所以,你可以这样做:

    ? "!"
    : "abc"
    

    【讨论】:

      猜你喜欢
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 2014-03-02
      • 2012-04-19
      • 2012-11-12
      • 1970-01-01
      相关资源
      最近更新 更多