목록 또는지도의 일부를 공유하기위한 YAML 구문이 있습니까?
그래서 나는 다음과 같이 할 수 있다는 것을 안다.
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
그리고이 sitelist
와 anotherlist
모두 포함 www.foo.com
하고 www.bar.com
. 그러나, 내가 정말 원하는 것은입니다 anotherlist
에 도 포함 www.baz.com
반복하지 않고, www.foo.com
하고 www.baz.com
.
이렇게하면 YAML 파서에서 구문 오류가 발생합니다.
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
- www.baz.com
앵커와 별칭을 사용하기 만하면 다음과 같은 다른 수준의 하위 구조를 추가하지 않고는 원하는 작업을 수행 할 수 없습니다.
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist:
- *sites
- www.baz.com
이는이 YAML 파일의 소비자가이를 알고 있어야 함을 의미합니다.
이와 같은 작업을 수행하는 순수한 YAML 방법이 있습니까? 아니면 변수 대체를 구현하거나 특정 종류의 하위 구조를 자동 해제하는 것과 같은 YAML 이후 처리를 사용해야합니까? 나는 이미 몇 가지 다른 사용 사례를 처리하기 위해 그런 종류의 사후 처리를 수행하고 있으므로 완전히 싫어하지는 않습니다. 그러나 내 YAML 파일은 기계 생성이 아닌 사람이 작성하므로 표준 YAML 구문 위에 사용자가 기억해야하는 규칙의 수를 최소화하고 싶습니다.
또한지도로 비슷한 일을 할 수 있기를 바랍니다.
namedsites: &sites
Foo: www.foo.com
Bar: www.bar.com
moresites: *sites
Baz: www.baz.com
YAML spec을 검색했는데 아무것도 찾을 수 없었기 때문에 대답은 "아니요 당신은 이것을 할 수 없습니다"라고 생각합니다. 그러나 누군가가 좋은 아이디어가 있다면.
편집 : 대답이 없었기 때문에 아무도 내가 YAML 사양에없는 것을 발견하지 못했고 YAML 레이어에서 수행 할 수 없다고 가정하고 있습니다. 그래서 누군가가 나중에이 질문을 찾을 경우를 대비하여 YAML을 사후 처리하는 아이디어에 대한 질문을 열어 보겠습니다.
병합 키 유형 은 아마도 원하는 것입니다. <<
병합을 나타 내기 위해 특수 매핑 키를 사용하여 매핑에 대한 별칭 (또는 이러한 별칭의 시퀀스)을 이니셜 라이저로 사용하여 단일 매핑으로 병합 할 수 있습니다. 또한 명시 적으로 값을 재정의하거나 병합 목록에없는 값을 더 추가 할 수 있습니다.
첫 번째 예로 시퀀스가 아닌 매핑과 함께 작동한다는 점에 유의하는 것이 중요합니다. 이것은 당신이 그것에 대해 생각할 때 의미가 있으며, 당신의 예는 아마도 어쨌든 순차적 일 필요가없는 것처럼 보입니다. 시퀀스 값을 매핑 키로 변경하는 것만으로도 다음 (예상되지 않은) 예제와 같이 트릭을 수행 할 수 있습니다.
sitelist: &sites
? www.foo.com # "www.foo.com" is the key, the value is null
? www.bar.com
anotherlist:
<< : *sites # merge *sites into this mapping
? www.baz.com # add extra stuff
주목할 몇 가지. 첫째, <<
키이므로 노드 당 한 번만 지정할 수 있습니다. 둘째, 시퀀스를 값으로 사용할 때 순서가 중요합니다. 관련 값이 없기 때문에 여기의 예제에서는 중요하지 않지만 알아 두어야 할 가치가 있습니다.
이전 답변에서 지적했듯이 YAML에서 목록 확장에 대한 기본 제공 지원이 없습니다. 나는 그것을 직접 구현하는 또 다른 방법을 제공하고 있습니다. 이걸 고려하세요:
defaults: &defaults
sites:
- www.foo.com
- www.bar.com
setup1:
<<: *defaults
sites+:
- www.baz.com
이것은 다음으로 처리됩니다.
defaults:
sites:
- www.foo.com
- www.bar.com
setup1:
sites:
- www.foo.com
- www.bar.com
- www.baz.com
The idea is to merge the contents of a key ending with a '+' to the corresponding key without a '+'. I implemented this in Python and published here.
Enjoy!
To clarify something from the two answers here, this is not supported directly in YAML for lists (but it is supported for dictionaries, see kittemon's answer).
(Answering my own question in case the solution I'm using is useful for anyone who searches for this in future)
With no pure-YAML way to do this, I'm going to implement this as a "syntax transformation" sitting between the YAML parser and the code that actually uses the configuration file. So my core application doesn't have to worry at all about any human-friendly redundancy-avoidance measures, and can just act directly on the resulting structures.
The structure I'm going to use looks like this:
foo:
MERGE:
- - a
- b
- c
- - 1
- 2
- 3
Which would be transformed to the equivalent of:
foo:
- a
- b
- c
- 1
- 2
- 3
Or, with maps:
foo:
MERGE:
- fork: a
spoon: b
knife: c
- cup: 1
mug: 2
glass: 3
Would be transformed to:
foo:
fork: a
spoon: b
knife: c
cup: 1
mug: 2
glass: 3
More formally, after calling the YAML parser to get native objects from a config file, but before passing the objects to the rest of the application, my application will walk the object graph looking for mappings containing the single key MERGE
. The value associated with MERGE
must be either a list of lists, or a list of maps; any other substructure is an error.
In the list-of-lists case, the entire map containing MERGE
will be replaced by the child lists concatenated together in the order they appeared.
In the list-of-maps case, the entire map containing MERGE
will be replaced by a single map containing all of the key/value pairs in the child maps. Where there is overlap in the keys, the value from the child map occurring last in the MERGE
list will be used.
The examples given above are not that useful, since you could have just written the structure you wanted directly. It's more likely to appear as:
foo:
MERGE:
- *salt
- *pepper
Allowing you to create a list or map containing everything in nodes salt
and pepper
being used elsewhere.
(I keep giving that foo:
outer map to show that MERGE
must be the only key in its mapping, which means that MERGE
cannot appear as a top-level name unless there are no other top level names)
Kittemon의 답변을 피기 백하려면 대체 구문을 사용하여 null 값으로 매핑을 만들 수 있습니다.
foo:
<< : myanchor
bar:
baz:
제안 된 구문 대신
foo:
<< : myanchor
? bar
? baz
Kittemon의 제안과 마찬가지로 매핑 내에서 앵커에 대한 참조를 사용하고 시퀀스 문제를 피할 수 있습니다. Symfony Yaml 구성 요소 v2.4.4가 ? bar
구문을 다시 구성하지 않는다는 사실을 발견 한 후이 작업을 수행해야한다는 것을 알게되었습니다 .
참고 URL : https://stackoverflow.com/questions/9254178/is-there-yaml-syntax-for-sharing-part-of-a-list-or-map
'program tip' 카테고리의 다른 글
정의되지 않은 동작을 포함하는 소스 코드가 컴파일러를 충돌시키는 것이 합법적입니까? (0) | 2020.10.15 |
---|---|
RESTful 웹 서비스에서 로그인을 어떻게 구현합니까? (0) | 2020.10.15 |
가변 템플릿 함수의 이기종 인수 팩에 대한 일반 계산을 수행하는 방법은 무엇입니까? (0) | 2020.10.15 |
이 모든 * .FileListAbsolute.txt 파일은 무엇입니까? (0) | 2020.10.15 |
라즈베리 파이의 모노 (0) | 2020.10.15 |