ExifTool has the ability to read and write XMP structures through the use of either structured or flattened tags. The ability to write via structured input was added in ExifTool version 8.44; older versions wrote using flattened tags only.
To illustrate the concept of a flattened tag, the XMP-exif:Flash
structure contains Fired
and Mode
fields (among
others). The flattened tags corresponding to these structure fields are
XMP-exif:FlashFired
and XMP-exif:FlashMode
.
This page describes various techniques used to read and write XMP structures using both structured and flattened tags.
When reading, structures are flattened by default, and ExifTool returns one "flattened" tag for each field in the structure:
> exiftool -xmp:all a.xmp XMP Toolkit : Image::ExifTool 8.44 Flash Fired : True Flash Mode : On Flash Return : Return not detected
But the -struct
option may be used to give structured
output. In this mode structures are returned instead of separate
"flattened" tags:
> exiftool -struct -xmp:all a.xmp XMP Toolkit : Image::ExifTool 8.44 Flash : {Fired=True,Mode=On,Return=Return not detected}
(Note: As illustrated in the example above, structures are
serialized for console output by the ExifTool
application. However, via the API with the Struct
option,
they are returned as Perl HASH references.)
The -struct
option may also be combined with the JSON
(-j
) or XML (-X
) output formats to provide a
structured format which may be more compatible with other applications.
When writing, flattened tags and structures may be used interchangeably. For example, the following commands all have the same effect.
exiftool -flashmode=on -flashreturn=not -flashfired=true a.xmp exiftool -xmp:flash="{mode=on,fired=true}" -flashreturn=not a.xmp exiftool -xmp:flash="{mode=on,fired=true,return=not}" a.xmp
(Note: Structures must be serialized when
writing via the command-line application, in the same format as when reading with
the -struct
option.)
An advantage of writing in structured form is that it can be easier to achieve the desired hierarchy with complex structures or when there are multiple structures in a list. For example, this command adds a new hierarchical keyword to the XMP-mwg-kw:HierarchicalKeywords list:
exiftool -hierarchicalkeywords+="{keyword=cat,children={keyword=Siamese}}" a.jpg
But the flattened tags may be more convenient for adding or replacing a single field in an existing structure because writing as a structure would requires that entire structure be replaced. For example, the following command adds a new second-level keyword to an existing HierarchicalKeywords structure:
exiftool -hierarchicalkeywords2+="Persian" a.jpg
Tricky: There is one drawback when using this technique to add new fields to existing structures in lists: New fields are added to the first structure which doesn't already contain the corresponding field. So before adding a new field to a arbitrary structure, dummy fields must first be added to all earlier structures in the list which are missing this field. However, the alternative of adding a new field by writing structured information also has its drawbacks. Here, although a specific structure in a list can easily be targeted through any unique combination of field values, the drawback is that the entire structure must be replaced (see Deleting / Replacing below).
The flattened tag names may also be used to write structures at any level in a complex hierarchy. The following example writes a third-level structure inside a HierarchicalKeywords structure:
exiftool -hierarchicalkeywords2Children='{Keyword=Tabby,Applied=true}' a.jpg
(Note: Containing structures are created as necessary. In this case, the HierarchicalKeywords and top-level KeywordInfo structures would be created if they didn't already exist.)
The order of structure fields is not significant, so they may be read in a different order then written, unlike arrays which maintain the same order. To give a predictable output, fields in structured information are sorted in alphabetical order of field name by ExifTool when reading and writing.
If there are errors converting some fields of the input structure,
other fields are still written and a warning is issued (but only one warning per
structure is reported). This also applies when copying structured information
except that the -v3
option must be used to see the warnings when
copying.
Programmers: Structured information is written and read as Perl HASH references via the ExifTool API, but they may also be written as serialized strings. The following two techniques are equivalent:
# as a serialized string $exifTool->SetNewValue('XMP:Flash' => '{mode=on,fired=true,return=not}'); # as a HASH reference $exifTool->SetNewValue('XMP:Flash' => { mode=>'on', fired=>'true', return=>'not' });
By default, tags are copied as structures. This allows the hierarchy of complex structures to be preserved when copying. In this mode, only the top-level structure tags may be specified:
# this copies the complete keyword hierarchy exiftool -tagsfromfile src.jpg -keywordinfo dst.jpg # WRONG because HierarchicalKeywords is NOT a top-level structure! exiftool -tagsfromfile src.jpg -hierarchicalkeywords dst.jpg
The copy-as-structure feature may be disabled with --struct
on
the command line, or by setting the Struct option to 0 via the API. Here is an
example command that copies the hierarchical keywords using this technique:
exiftool -tagsfromfile src.jpg --struct "-hierarchicalkeywords*" dst.jpg
(Note: Copying as flattened tags, as in the command above, was the default behaviour with ExifTool 8.43 and earlier. But copying as structures has been the default since the ability to write structured information was introduced in version 8.44.)
A complete structure is deleted by specifying one or more matching
fields. For example, the following command deletes all HierarchicalKeywords
structures which have the Keyword "Terrier
" at the second level:
exiftool -hierarchicalkeywords-="{Children={Keyword=Terrier}}" a.jpg
Structure fields may also be deleted individually using the flattened tag names. The following command deletes only the matching fields from the second-level of all HierarchicalKeywords structures:
exiftool -hierarchicalkeywords2-="Terrier" a.jpg
When deleting and adding back items in lists in the same command, new items are inserted at the point in the list where the first item was removed, or at the end of the list if no items were deleted. This applies to lists of structures as well as simple lists of string values, and provides a mechanism to replace a specific structure or field.
Structure field names use a format very similar to tag names in ExifTool. The following table lists some similarities and differences between tag names and structure field names:
† Except that group name prefixes are allowed in structures which support arbitrary XMP fields (ie. Region Extensions)
Feature Example Tag Names Field Names Case Insensitivity Title, title, TITLE Yes Yes Alternate Language Suffix Title-de Yes Yes Numerical Value Suffix Mode# Yes Yes Group Name Prefix XMP-dc:Title Yes No†
|
):
|
) and commas (,
) anywhere in the string}
) anywhere in structure field values]
) anywhere in list items{
) or square ([
)
bracket, or whitespace character (SPACE, TAB, CR or LF) if it appears at the
beginning of the string=
)
to separate field names from their corresponding values, and a comma between
structure fields.For example, with a command like this:
exiftool "-RegionInfo<=INFILE" a.xmp
the INFILE below may be used to write structured information to XMP:RegionInfo.
{ AppliedToDimensions = { W = 4288, H = 2848, Unit = pixel, }, RegionList = [ { Area = { W = 0.15, H = 0.17, X = 0.3, Y = 0.4, Unit = normalized, }, Description = A Physics Icon {relatively speaking|}, Name = Albert Einstein, Type = Face, Extensions = { XMP-xmpRights:UsageTerms = copyright Phil Harvey, XMP-xmpRights:UsageTerms-fr = droit d'auteur Phil Harvey, }, SeeAlso = dc:subject, }, { Area = { W = 0.06, H = 0.09, X = 0.5, Y = 0.6, Unit = normalized, }, Description = this is a test|, what did you expect?, Type = Focus, FocusUsage = EvaluatedUsed, } ], }
In this example, white space has been added in all allowed locations for demonstration purposes and to improve readability. Also, optional commas have been added after the last field of each structure. (Note that a comma may NOT be added after the last item in a list because this would be interpreted as an additional list item of a zero-length string.)
User-defined XMP structure tags may be created via the ExifTool config file. See the NewXMPxxxStruct tag definition in the XMP-xxx examples of the sample config file for more details.