-
-
Notifications
You must be signed in to change notification settings - Fork 23
yaml merge Anchor Options
This document is part of the body of knowledge about yaml-merge, one of the reference command-line tools provided by the YAML Path project.
The yaml-merge
command-line tool enables users to control how it handles conflicting Anchors during a merge operation. Non-conflicting Anchors are automatically merged and the definition-use order between each Anchor and its Aliases is preserved during the merge. An Anchor conflict occurs only when the same Anchor name is used in both of the LHS and RHS documents and the Anchored value is different between them.
Any attempt to merge with Anchor conflicts when using default options will result in an error. This is because the yaml-merge
tool will refuse any operation which would destroy data unless the user explicitly instructs it to do so, and how. Not all Anchor conflict resolution options are destructive; the rename
option preserves all Anchors and their Aliases in both documents by uniquely renaming conflicting Anchors and Aliases in the RHS document.
But what are Anchors? In short:
Anchors are a name assigned to a Scalar or Hash (AKA: Map, Dictionary) YAML data element. This name is prefixed with an
&
sign. Beyond that point within the same YAML document, the data which was "anchored" can be re-used any number of times by referencing the Anchor via its Alias form whereby the&
is replaced with an*
sign.
In other words, YAML defines two kinds of Anchors. Scalar Anchors define reusable Scalar values (which are String, Integer, Float, Boolean, etc. data types). Hash Anchors (AKA Map Anchors or Dictionary Anchors) define a reusable set of key-value pairs which can be merged into other Hashes within the same document using their YAML Merge Keys (<<:
). To date, there is no definition in YAML for an Array Anchor (AKA List Anchor or Sequence Anchor).
Each of these Anchor types will be explored in how they are merged based on user option selection. When there is no conflict, RHS Anchors are merged into the LHS document no matter what Anchor merge option is selected. In order to resolve Anchor conflicts, the yaml-merge
tool's available Anchor merge options include:
-
stop
(the default) causes merging to abort upon detection of an Anchor conflict. -
left
causes LHS Anchors to overwrite conflicting RHS Anchors. -
right
causes RHS Anchors to overwrite conflicting LHS Anchors. -
rename
causes RHS Anchors to be automatically and uniquely renamed before they are merged into the LHS document. The RHS document is updated to use the new Anchor name everywhere its Aliases appear before the merge.
Scalar Anchors create a single value which can be reused in multiple places within the same YAML document. This enables YAML file authors to institute "One Version of the Truth", enabling a change in exactly one place to affect an identical change everywhere that same change is needed. By convention, they are usually gathered up into a special Array named aliases:
near the top of each YAML file. Such a file might look like:
File: LHS1.yaml
---
aliases:
- &scalar_anchor_string This is a reusable String value
- &scalar_anchor_integer 5280
a_hash:
which_reuses:
those_anchors:
string_alias: *scalar_anchor_string
integer_alias: *scalar_anchor_integer
in_several_places:
string_alias: *scalar_anchor_string
integer_alias: *scalar_anchor_integer
Were you to query the YAML file at /a_hash/which_reuses/those_anchors/string_alias
(or a_hash.which_reuses.those_anchors.string_alias
), you'd get back This is a reusable String value
:
yaml-get --query=/a_hash/which_reuses/those_anchors/string_alias LHS1.yaml
This is a reusable String value
We can impose an Anchor conflict by attempting to merge with:
File: RHS1.yaml
---
aliases:
- &scalar_anchor_string A DIFFERENT STRING VALUE
- &scalar_anchor_integer 5280
another_hash:
another_alias_string: *scalar_anchor_string
another_alias_integer: *scalar_anchor_integer
Notice that RHS1.yaml redefines &scalar_anchor_string
but not &scalar_anchor_integer
. In this case, only &scalar_anchor_string
is in conflict. A query against /another_hash/another_alias_string
(or another_hash.another_alias_string
) in RHS1.yaml would yield the expected value:
yaml-get --query=/another_hash/another_alias_string RHS1.yaml
A DIFFERENT STRING VALUE
The next sub-sections are examples of the various ways to deal with such an Anchor conflict.
You can instruct yaml-merge
to override the value of conflicting Anchors in the RHS document. By setting --anchors=left
or -a left
, yaml-merge
would produce this output:
---
aliases:
- &scalar_anchor_string This is a reusable String value
- &scalar_anchor_integer 5280
- *scalar_anchor_string
- *scalar_anchor_integer
a_hash:
which_reuses:
those_anchors:
string_alias: *scalar_anchor_string
integer_alias: *scalar_anchor_integer
in_several_places:
string_alias: *scalar_anchor_string
integer_alias: *scalar_anchor_integer
another_hash:
another_alias_string: *scalar_anchor_string
another_alias_integer: *scalar_anchor_integer
Notice that the RHS Anchors were turned into Aliases of the same-named LHS Anchors. Because the default option for Arrays is to preserve all
elements from both documents during the merge, the aliases:
array receives the redefined Anchors-as-Aliases from the RHS document. This is normal and you can override this behavior.
If you were to repeat the previous two queries against the merged document, and inspect the resulting aliases:
Array, you'd get:
yaml-merge --anchors=left LHS1.yaml RHS1.yaml | yaml-get --query=/a_hash/which_reuses/those_anchors/string_alias -
This is a reusable String value
yaml-merge --anchors=left LHS1.yaml RHS1.yaml | yaml-get --query=/another_hash/another_alias_string -
This is a reusable String value
yaml-merge --anchors=left LHS1.yaml RHS1.yaml | yaml-get --query=/aliases -
["This is a reusable String value", 5280, "This is a reusable String value", 5280]
You can instruct yaml-merge
to override the value of conflicting Anchors in the LHS document. By setting --anchors=right
or -a right
, yaml-merge
would produce this output:
---
aliases:
- &scalar_anchor_string A DIFFERENT STRING VALUE
- &scalar_anchor_integer 5280
- *scalar_anchor_string
- *scalar_anchor_integer
a_hash:
which_reuses:
those_anchors:
string_alias: *scalar_anchor_string
integer_alias: *scalar_anchor_integer
in_several_places:
string_alias: *scalar_anchor_string
integer_alias: *scalar_anchor_integer
another_hash:
another_alias_string: *scalar_anchor_string
another_alias_integer: *scalar_anchor_integer
Notice that the conflicting RHS Anchor (&scalar_anchor_string
) has replaced the original LHS value. As with the right
behavior and because the default option for Arrays is to preserve all
elements from both documents during the merge, the aliases:
array again shows the redefined Anchors-as-Aliases from the LHS and RHS documents. This is normal and you can override this behavior.
If you were to repeat the previous two queries against the merged document, and inspect the resulting aliases:
Array, you'd get:
yaml-merge --anchors=right LHS1.yaml RHS1.yaml | yaml-get --query=/a_hash/which_reuses/those_anchors/string_alias -
A DIFFERENT STRING VALUE
yaml-merge --anchors=right LHS1.yaml RHS1.yaml | yaml-get --query=/another_hash/another_alias_string -
A DIFFERENT STRING VALUE
yaml-merge --anchors=right LHS1.yaml RHS1.yaml | yaml-get --query=/aliases -
["A DIFFERENT STRING VALUE", 5280, "A DIFFERENT STRING VALUE", 5280]
You may not always wish to override the values of Scalar Anchors during a merge. In some cases, such collisions may be accidental and you really need both documents' Anchors to be preserved during the merge. For this and similar cases, yaml-merge
supports a rename
option for handling Anchor collisions. By setting --anchors=rename
or -a rename
, yaml-merge
would produce this output:
---
aliases:
- &scalar_anchor_string This is a reusable String value
- &scalar_anchor_integer 5280
- &scalar_anchor_string_1 A DIFFERENT STRING VALUE
- *scalar_anchor_integer
a_hash:
which_reuses:
those_anchors:
string_alias: *scalar_anchor_string
integer_alias: *scalar_anchor_integer
in_several_places:
string_alias: *scalar_anchor_string
integer_alias: *scalar_anchor_integer
another_hash:
another_alias_string: *scalar_anchor_string_1
another_alias_integer: *scalar_anchor_integer
Notice that the conflicting RHS Anchor (&scalar_anchor_string
) was renamed to &scalar_anchor_string_1
. Throughout the rest of the merged document, all uses of the previously-conflicting Anchor name have been renamed to match this change, fully preserving both the LHS and RHS documents in the merged result. Note also that the non-conflicting anchor (&scalar_anchor_integer
) caused no disruption and seamlessly integrated with the LHS original. Because the default option for Arrays is to preserve all
elements from both documents during the merge, the aliases:
array again shows the redefined Anchor-as-Alias for this non-conflicting element. This is normal and you can override this behavior.
If you were to repeat the previous two queries against the merged document, and inspect the resulting aliases:
Array, you'd get:
yaml-merge --anchors=rename LHS1.yaml RHS1.yaml | yaml-get --query=/a_hash/which_reuses/those_anchors/string_alias -
This is a reusable String value
yaml-merge --anchors=rename LHS1.yaml RHS1.yaml | yaml-get --query=/another_hash/another_alias_string -
A DIFFERENT STRING VALUE
yaml-merge --anchors=rename LHS1.yaml RHS1.yaml | yaml-get --query=/aliases -
["This is a reusable String value", 5280, "A DIFFERENT STRING VALUE", 5280]
In most cases, this is probably the preferred outcome.
Hash Anchors are quite a bit more complex than Scalar Anchors. In turn, they are extremely useful at reducing duplication of Hash structure and simultaneously reusing more than one key-value pair. Rather than create a single data element (a Scalar value) which can be reused throughout the remainder of the YAML document, a Hash Anchor enables repeatedly reusing an entire Hash. Any number of the key-value pairs within the Anchored Hash can be discretely overridden at each point of reuse, allowing "defaults" within the Anchored Hash to be set to concrete values. Further, multiple Anchored Hashes can be combined to produce novel combinations of reusable Hash fragments.
A simple example might be a short set of publications, like:
File: LHS2a.yaml
book_defaults: &defaults
author: UNKNOWN
publisher: UNKNOWN
publication_year: UNKNOWN
publications:
books:
'A Novel':
<<: *defaults
author: John Doe
publisher: Books-R-Us
'A Tech Manual':
<<: *defaults
publication_year: 1998
contributing_authors:
- Jane Doe
- Billy Bob Joe Frank
Note that Hash Anchor names come after the name of the Hash being Anchored and the name of the Anchor does not need to match the name of the key defining the reusable Hash; this is the reverse of Scalar Anchors. Notice also the YAML Merge Key, <<:
, later in the document. When present in YAML files, the YAML Merge Key is an instruction to embed only those keys (and their values) from the source Anchored Hash which are not locally defined for the target Hash (only copy keys not already defined). This is all separate from the capabilities provided by the yaml-merge
tool; this very powerful capability is just native YAML.
To explore this concept, consider these queries and their results:
yaml-get --query='/&defaults' LHS2.yaml
{"author": "UNKNOWN", "publisher": "UNKNOWN", "publication_year": "UNKNOWN"}
yaml-get --query="/publications/books/'A Novel'" LHS2.yaml
{"author": "John Doe", "publisher": "Books-R-Us", "publication_year": "UNKNOWN"}
yaml-get --query="/publications/books/'A Tech Manual'" LHS2.yaml
{"publication_year": 1998, "contributing_authors": ["Jane Doe", "Billy Bob Joe Frank"], "author": "UNKNOWN", "publisher": "UNKNOWN"}
You can see that each book record always has all of the fields provided by the &defaults
Anchored Hash, even when the data for the book is not specified. Further, novel fields in a book record extend the definition of the record, beyond the fields provided by the default.
Note that it is convention to place the YAML Merge Key as the first child of a Hash being internally merged. However, the operator could be at any child position within the Hash. The specification (draft) for this operator specifically stipulates that a YAML Merge Key will never cause any existing keys already defined within the target Hash to be overwritten. This holds true even when merging multiple Anchored Hashes into the same Hash; only the first instance of any given unused key from the Anchored Hash list (processed left-to-right, top-to-bottom) is merged in, and any locally-defined keys always override same-named keys from the Anchored Hashes.
Hash Anchors get even more delightfully complex than this, enabling further specialization and reuse of Hash fragments. Let's say that book and magazine publications share some attributes, but not all. Further, let's assume our data provider keeps book data apart from magazine data in some back-end storage solution. Should we need to merge such data together for further aggregation or analysis, we could encounter an Anchor merge conflict.
Take these two YAML files for example:
File: LHS2b.yaml
publication_defaults: &pubdefs
publisher: UNKNOWN
publication_year: UNKNOWN
book_defaults: &defaults
author: UNKNOWN
publications:
books:
'A Novel':
<<:
- *pubdefs
- *defaults
author: John Doe
publisher: Books-R-Us
'A Tech Manual':
<<: [*pubdefs, *defaults]
publication_year: 1998
contributing_authors:
- Jane Doe
- Billy Bob Joe Frank
File: RHS2.yaml
publication_defaults: &pubdefs
publisher: UNKNOWN
publication_year: UNKNOWN
magazine_defaults: &defaults
glossy: false
serial_number: UNKNOWN
publications:
magazines:
'Video Games Today':
<<: [*pubdefs, *defaults]
glossy: true
publication_year: 1994
serial_number: 7
'Bigger Trucks':
<<: [*pubdefs, *defaults]
publication_year: 2020
We are now composing our records by using Anchored Hash fragments. In our fictional case, each record uses both fragments but this needn't always be the case. Purely for demonstration, LHS2b.yaml presents the YAML Merge Key's arguments (both Aliases) in two styles: block and flow. By convention, flow style is normally used but the two forms are equivalent. The yaml-merge
tool uses the flow style when writing out its results.
Excepting that the &defaults
Anchored Hash is now a fragment, performing the same queries as before against LHS2b.yaml yields the same answers:
yaml-get --query='/&pubdefs' LHS2b.yaml
{"publisher": "UNKNOWN", "publication_year": "UNKNOWN"}
yaml-get --query='/&defaults' LHS2b.yaml
{"author": "UNKNOWN"}
yaml-get --query="/publications/books/'A Novel'" LHS2b.yaml
{"author": "John Doe", "publisher": "Books-R-Us", "publication_year": "UNKNOWN"}
yaml-get --query="/publications/books/'A Tech Manual'" LHS2b.yaml
{"publication_year": 1998, "contributing_authors": ["Jane Doe", "Billy Bob Joe Frank"], "publisher": "UNKNOWN", "author": "UNKNOWN"}
For contrast with later examples, here are some queries against RHS2.yaml:
yaml-get --query='/&pubdefs' RHS2.yaml
{"publisher": "UNKNOWN", "publication_year": "UNKNOWN"}
yaml-get --query='/&defaults' RHS2.yaml
{"glossy": false, "serial_number": "UNKNOWN"}
yaml-get --query="/publications/magazines/'Video Games Today'" RHS2.yaml
{"glossy": true, "publication_year": 1994, "serial_number": 7, "publisher": "UNKNOWN"}
yaml-get --query="/publications/magazines/'Bigger Trucks'" RHS2.yaml
{"publication_year": 2020, "publisher": "UNKNOWN", "glossy": false, "serial_number": "UNKNOWN"}
Can you see where an Anchor merge conflict will occur when we attempt to merge RHS2.yaml into LHS2b.yaml? Answer: the &defaults
Anchor name is being used on two different Hashes between LHS2b.yaml and RHS2.yaml; this is the conflict. The &pubdefs
Anchor is non-conflicting because the Hash defined in both documents is identical.
Let's take a look at the various means by which the yaml-merge
tool can deal with this conflict. Some are more useful than others.
When you are absolutely certain that all Hash Anchor definitions in the LHS document are absolute and mustn't be overridden by any RHS re-definitions, use --anchors=left
or -a left
. Doing so in the example case produces this document:
---
publication_defaults: &pubdefs
publisher: UNKNOWN
publication_year: UNKNOWN
book_defaults: &defaults
author: UNKNOWN
magazine_defaults: *defaults
publications:
books:
'A Novel':
<<: [*pubdefs, *defaults]
author: John Doe
publisher: Books-R-Us
'A Tech Manual':
<<: [*pubdefs, *defaults]
publication_year: 1998
contributing_authors:
- Jane Doe
- Billy Bob Joe Frank
magazines:
'Video Games Today':
<<: [*pubdefs, *defaults]
glossy: true
publication_year: 1994
serial_number: 7
'Bigger Trucks':
<<: [*pubdefs, *defaults]
publication_year: 2020
You can see that the conflicting definition of &defaults
from the RHS document was overwritten by the LHS definition. This resulted in some expected data loss; the keys unique to magazine_defaults
were destroyed to make magazine_defaults
a copy of publication_defaults
. For our case, this isn't particularly helpful but it is exactly what we instructed yaml-merge
to do.
If we re-run every query against the merged result, we see some interesting -- albeit unhelpful -- changes:
yaml-merge --anchors=left LHS2b.yaml RHS2.yaml | yaml-get --query='/&pubdefs' -
{"publisher": "UNKNOWN", "publication_year": "UNKNOWN"}
yaml-merge --anchors=left LHS2b.yaml RHS2.yaml | yaml-get --query='/&defaults' -
{"author": "UNKNOWN"}
{"author": "UNKNOWN"}
yaml-merge --anchors=left LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/books/'A Novel'" -
{"author": "John Doe", "publisher": "Books-R-Us", "publication_year": "UNKNOWN"}
yaml-merge --anchors=left LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/books/'A Tech Manual'" -
{"publication_year": 1998, "contributing_authors": ["Jane Doe", "Billy Bob Joe Frank"], "publisher": "UNKNOWN", "author": "UNKNOWN"}
yaml-merge --anchors=left LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/magazines/'Video Games Today'" -
{"glossy": true, "publication_year": 1994, "serial_number": 7, "publisher": "UNKNOWN", "author": "UNKNOWN"}
yaml-merge --anchors=left LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/magazines/'Bigger Trucks'" -
{"publication_year": 2020, "publisher": "UNKNOWN", "author": "UNKNOWN"}
Of note:
-
--query='/&defaults'
now returns two matches rather than just one. This is becausemagazine_defaults
is both a complete duplicate ofbook_defaults
and still a separate Hash in the root of the document. -
--query="/publications/magazines/'Video Games Today'"
now has anauthor
attribute, injected from the re-defined&defaults
Anchored Hash. -
--query="/publications/magazines/'Bigger Trucks'"
now has anauthor
attribute (same reason as above) and lost itsglossy
attribute (because we destroyed it by forcing the left Anchor definition to overwrite the RHS definition. - All other answers are identical.
When you are absolutely certain that all Hash Anchor re-definitions in the RHS document are absolute and must overwrite any conflicting LHS definitions, use --anchors=right
or -a right
. Doing so in the example case produces this document:
---
publication_defaults: &pubdefs
publisher: UNKNOWN
publication_year: UNKNOWN
book_defaults: &defaults
glossy: false
serial_number: UNKNOWN
magazine_defaults: *defaults
publications:
books:
'A Novel':
<<: [*pubdefs, *defaults]
author: John Doe
publisher: Books-R-Us
'A Tech Manual':
<<: [*pubdefs, *defaults]
publication_year: 1998
contributing_authors:
- Jane Doe
- Billy Bob Joe Frank
magazines:
'Video Games Today':
<<: [*pubdefs, *defaults]
glossy: true
publication_year: 1994
serial_number: 7
'Bigger Trucks':
<<: [*pubdefs, *defaults]
publication_year: 2020
You can see that the conflicting definition of &defaults
from the RHS document overwrote the original LHS definition. The book_defaults
Hash was overwritten with the structure and content of magazine_defaults
from the RHS document. This resulted in some expected data loss; the keys unique to book_defaults
were destroyed to make it a full copy of magazine_defaults
. As with Left Hash Anchor Override, this isn't particularly helpful but it is exactly what we instructed yaml-merge
to do.
If we re-run every query against the merged result, we see some interesting -- arguably unhelpful -- changes:
yaml-merge --anchors=right LHS2b.yaml RHS2.yaml | yaml-get --query='/&pubdefs' -
{"publisher": "UNKNOWN", "publication_year": "UNKNOWN"}
yaml-merge --anchors=right LHS2b.yaml RHS2.yaml | yaml-get --query='/&defaults' -
{"glossy": false, "serial_number": "UNKNOWN"}
{"glossy": false, "serial_number": "UNKNOWN"}
yaml-merge --anchors=right LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/books/'A Novel'" -
{"author": "John Doe", "publisher": "Books-R-Us", "publication_year": "UNKNOWN", "glossy": false, "serial_number": "UNKNOWN"}
yaml-merge --anchors=right LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/books/'A Tech Manual'" -
{"publication_year": 1998, "contributing_authors": ["Jane Doe", "Billy Bob Joe Frank"], "publisher": "UNKNOWN", "glossy": false, "serial_number": "UNKNOWN"}
yaml-merge --anchors=right LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/magazines/'Video Games Today'" -
{"glossy": true, "publication_year": 1994, "serial_number": 7, "publisher": "UNKNOWN"}
yaml-merge --anchors=right LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/magazines/'Bigger Trucks'" -
{"publication_year": 2020, "publisher": "UNKNOWN", "glossy": false, "serial_number": "UNKNOWN"}
Of note:
-
--query='/&defaults'
again returns two matches rather than just one. This is becausemagazine_defaults
is both a complete duplicate of the redefinedbook_defaults
Hash and still a separate Hash in the root of the document. -
--query="/publications/books/'A Novel'"
now hasglossy
andserial_number
attributes. -
--query="/publications/books/'A Tech Manual'"
also now has bothglossy
andserial_number
attributes but lost itsauthor
attribute. - All other answers are identical.
In most -- but certainly not all -- cases, this is the best Anchor conflict resolution option. It wholly preserves every Anchored Hash and their Aliases, fully preserving the crucial data from all merged documents. When setting --anchors=rename
or -a rename
, a more useful document is generated for this example use-case:
---
publication_defaults: &pubdefs
publisher: UNKNOWN
publication_year: UNKNOWN
book_defaults: &defaults
author: UNKNOWN
magazine_defaults: &defaults_1
glossy: false
serial_number: UNKNOWN
publications:
books:
'A Novel':
<<: [*pubdefs, *defaults]
author: John Doe
publisher: Books-R-Us
'A Tech Manual':
<<: [*pubdefs, *defaults]
publication_year: 1998
contributing_authors:
- Jane Doe
- Billy Bob Joe Frank
magazines:
'Video Games Today':
<<: [*pubdefs, *defaults_1]
glossy: true
publication_year: 1994
serial_number: 7
'Bigger Trucks':
<<: [*pubdefs, *defaults_1]
publication_year: 2020
The Anchor conflict was resolved by renaming the conflicting Anchor from the RHS document to &defaults_1
. At this point, no data was lost and the original queries return the same results from the two original documents excepting that we must use the new Anchor name to find the new definition of magazine_defaults
by its Anchor name. [NOTE: We could just search for /magazine_defaults
to find it but if we had to search by its Anchor name, it will have changed in the merged document.] The original queries against the merged document now return the original data:
yaml-merge --anchors=rename LHS2b.yaml RHS2.yaml | yaml-get --query='/&pubdefs' -
{"publisher": "UNKNOWN", "publication_year": "UNKNOWN"}
yaml-merge --anchors=rename LHS2b.yaml RHS2.yaml | yaml-get --query='/&defaults' -
{"author": "UNKNOWN"}
yaml-merge --anchors=rename LHS2b.yaml RHS2.yaml | yaml-get --query='/&defaults_1' -
{"glossy": false, "serial_number": "UNKNOWN"}
yaml-merge --anchors=rename LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/books/'A Novel'" -
{"author": "John Doe", "publisher": "Books-R-Us", "publication_year": "UNKNOWN"}
yaml-merge --anchors=rename LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/books/'A Tech Manual'" -
{"publication_year": 1998, "contributing_authors": ["Jane Doe", "Billy Bob Joe Frank"], "publisher": "UNKNOWN", "author": "UNKNOWN"}
yaml-merge --anchors=rename LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/magazines/'Video Games Today'" -
{"glossy": true, "publication_year": 1994, "serial_number": 7, "publisher": "UNKNOWN"}
yaml-merge --anchors=rename LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/magazines/'Bigger Trucks'" -
{"publication_year": 2020, "publisher": "UNKNOWN", "glossy": false, "serial_number": "UNKNOWN"}
With a now-complete data-set, we could run some more interesting queries, like:
# Identify all KNOWN Publication Years in ALL of the publications:
yaml-merge --anchors=rename LHS2b.yaml RHS2.yaml | yaml-get --query="/publications/[.!='']/[.!='']/[publication_year!=UNKNOWN]" -
1998
1994
2020
While the yaml-merge
tool can read per YAML Path merging options from an INI-Style configuration file via its --config
(-c
) argument, this is not supported for Anchor conflict resolutions. You can however, set a default resolution in the [defaults]
section.
The [defaults]
section permits a key named, anchors
, which behaves identically to the --anchors
(-a
) command-line argument to the yaml-merge
tool. The [defaults]anchors
setting is overridden by the same-named command-line argument, when supplied. In practice, this file may look like:
File merge-options.ini
[defaults]
anchors = rename
Note the spaces around the =
sign are optional but only an =
sign may be used to separate each key from its value.
At this time, Anchors are handled only in the document-wide scope. The [rules]
section does not support specifying per YAML Path Anchor resolution options.