File: struct.html

package info (click to toggle)
libimage-exiftool-perl 11.16-1%2Bdeb10u1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 24,024 kB
  • sloc: perl: 245,177; xml: 120; makefile: 9
file content (431 lines) | stat: -rw-r--r-- 19,437 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
  <title>Structured Information</title>
<link rel=stylesheet type='text/css' href='style.css' title='Style'>
<style type="text/css">
<!--
pre  { padding: 0; margin: 0px 2px }
spc  { margin-top: 5em }
li   { margin-top: .5em }
li.c { margin-top: 0 }
-->
</style>
</head>
<body>
<div class='index'>
<a href="#Reading">Reading</a>
<br><a href="#Writing">Writing</a>
<br><a href="#Copying">Copying</a>
<br><a href="#Deleting">Deleting</a>
<br><a href="#Fields">Field Names</a>
<br><a href="#Serialize">Serialization</a>
<br><a href="#Examples">Examples</a>
<br><a href="#User">User-Defined</a>
</div>
<h1 class='up'>Structured Information</h1>

<p>ExifTool has the ability to read and write XMP structures through the use of
either <b>structured or flattened tags</b>.  The ability to write via structured
input was added in ExifTool version 8.44; older versions accepted only flattened
tags as input.</p>

<p>To illustrate the concept of a flattened tag, the <code>XMP-exif:Flash</code>
structure contains <code>Fired</code> and <code>Mode</code> fields (among
others).  The flattened tags corresponding to these structure fields are
<code>XMP-exif:FlashFired</code> and <code>XMP-exif:FlashMode</code>.  In the
<a href="TagNames/XMP.html">XMP Tags documentation</a>, flattened tags are
indicated by an underline (<code>_</code>) after the Writable type.</p>

<p>This page describes various techniques used to read and write XMP structures
using both structured and flattened tags.</p>

<a name='Reading'></a>
<h2>Reading</h2>

<p>When reading, structures are <b>flattened by default</b>, and ExifTool
returns one "flattened" tag for each field in the structure:</p>

<blockquote><table class='box'><tr><td>
<pre>&gt; <span class=code>exiftool -xmp:all a.xmp</span>
XMP Toolkit                     : Image::ExifTool 8.44
Flash Fired                     : True
Flash Mode                      : On
Flash Return                    : Return not detected</pre>
</td></tr></table></blockquote>

<p>But the <code>-struct</code> option may be used to give <b>structured
output</b>.  In this mode structures are returned instead of separate
"flattened" tags:</p>

<blockquote><table class='box'><tr><td>
<pre>&gt; <span class=code>exiftool -struct -xmp:all a.xmp</span>
XMP Toolkit                     : Image::ExifTool 8.44
Flash                           : {Fired=True,Mode=On,Return=Return not detected}</pre>
</td></tr></table></blockquote>

<p class=lt>(Note: As illustrated in the example above, structures are
<a href='#Serialize'>serialized</a> for console output by the ExifTool
application. However, via the API with the <code>Struct</code> option,
they are returned as Perl HASH references.)</p>

<p>The <code>-struct</code> option may also be combined with the JSON
(<code>-j</code>), PHP (<code>-php</code>) or XML (<code>-X</code>) output
formats to provide a structured format which may be more compatible with other
applications.</p>

<a name='Writing'></a>
<h2>Writing</h2>

<p>When writing, <b>flattened tags and structures may be used interchangeably</b>.
For example, the following commands all have the same effect.</p>

<blockquote><table class='box'><tr><td>
<pre class=code>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</pre>
</td></tr></table></blockquote>

<p class=lt>(Note:  Structures must be <a href='#Serialize'>serialized</a> when
writing via the command-line application, in the same format as when reading with
the <code>-struct</code> option.)</p>

<p>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:</p>

<blockquote><table class='box'><tr><td>
<pre class=code>exiftool -hierarchicalkeywords+="{keyword=cat,children={keyword=Siamese}}" a.jpg</pre>
</td></tr></table></blockquote>

<p>But the flattened tags may be more convenient for <b>adding or replacing a
single field</b> in an existing structure because writing as a structure would
require that the entire structure be replaced.  For example, the following command
adds a new second-level keyword to an existing HierarchicalKeywords structure:</p>

<blockquote><table class='box'><tr><td>
<pre class=code>exiftool -hierarchicalkeywords2+="Persian" a.jpg</pre>
</td></tr></table></blockquote>

<p><b>Tricky:</b> 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 <a href="#Deleting">Deleting / Replacing</a>
below).</p>

<p>The flattened tag names may also be used to <b>write structures at any level
in a complex hierarchy</b>.  The following example writes a third-level
structure inside a HierarchicalKeywords structure:</p>

<blockquote><table class='box'><tr><td>
<pre class=code>exiftool -hierarchicalkeywords2Children='{Keyword=Tabby,Applied=true}' a.jpg</pre>
</td></tr></table></blockquote>

<p class=lt>(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.)</p>

<p>The <b>order of structure fields is not significant</b>, so they may be read
in a different order than written, unlike arrays which maintain the same order. 
To give a predictable output, fields in structured information are <b>sorted in
alphabetical order</b> of field name by ExifTool when reading and writing.</p>

<p>If there are <b>errors converting some fields</b> 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 <code>-v3</code> option must be used to see the warnings when
copying.</p>

<p><b>Programmers:</b> Structured information is written and read as Perl HASH
references via the ExifTool API, but it may also be written as a serialized
string.  The following two techniques are equivalent:</p>

<blockquote><table class='box'><tr><td>
<pre># as a HASH reference
<span class=code>$exifTool-&gt;SetNewValue('XMP:Flash' =&gt; { mode=>'on', fired=>'true', return=>'not' });
</span>
# as a serialized string
<span class=code>$exifTool-&gt;SetNewValue('XMP:Flash' =&gt; '{mode=on,fired=true,return=not}');</span></pre>
</td></tr></table></blockquote>

<a name='Copying'></a>
<h2>Copying</h2>

<p>By default, tags are <b>copied as structures</b>, but flattened tag names
may still be copied by specifying them explicitly. <span class=lt>(Flattened
tags are treated as "unsafe" for copying so they are not copied by default
unless the Struct feature is disabled; see below.)</span> Copying as structures
allows the hierarchy of complex structures to be preserved.</p>

<blockquote><table class='box'><tr><td>
<pre># this copies all XMP information as structures
# (flattened tags are not copied by default...)
<span class=code>exiftool -tagsfromfile src.jpg -xmp:all dst.jpg
</span>
# ... but flattened tags may be copied individually.  Here the
# first level hierarchical keywords are copied to the Subject tag
# (this may be done in the same command as one that copies structures)
<span class=code>exiftool -tagsfromfile src.jpg "-subject&lt;hierarchicalkeywords1" dst.jpg</span></pre>
</td></tr></table></blockquote>

<p>Note that when copying a specific structure, only the top-level structures
may be specified:</p>

<blockquote><table class='box'><tr><td>
<pre># this copies the complete keyword hierarchy
<span class=code>exiftool -tagsfromfile src.jpg -keywordinfo dst.jpg
</span>
# WRONG because HierarchicalKeywords is NOT a top-level structure!
<span class=code>exiftool -tagsfromfile src.jpg -hierarchicalkeywords dst.jpg</span></pre>
</td></tr></table></blockquote>

<p>The copy-as-structure feature may be disabled with <code>--struct</code> on
the command line, or by setting the <a href="ExifTool.html#Struct">Struct option</a>
to 0 via the API.  When this is done, only flattened tags are copied, and
structures may not be specified. Conversely, if the structure option is enabled
(by setting the <a href="ExifTool.html#Struct">Struct option</a> to 1 via the API,
or with <code>-struct</code> on the command line), only structures are copied,
and flattened tags may not be specified.</p>

<p class=lt>(Note: ExifTool 8.43 and earlier copied as flattened tags only, but
copying as structures has been the default since the ability to write structured
information was introduced in version 8.44.  An enhancement in version 8.82
allowed flattened tags to be copied explicitly without the need to disable the
Struct option.)</p>

<a name='Deleting'></a>
<h2>Deleting / Replacing</h2>

<p>A <b>complete structure is deleted</b> by specifying one or more matching
fields.  All fields must match for the structure to be deleted.  For example,
the following command deletes all HierarchicalKeywords structures which have the
Keyword "<code>Terrier</code>" at the second level:</p>

<blockquote><table class='box'><tr><td>
<pre class=code>exiftool -hierarchicalkeywords-="{Children={Keyword=Terrier}}" a.jpg</pre>
</td></tr></table></blockquote>

<p>Structure <b>fields may also be deleted individually</b> using the flattened
tag names.  The following command deletes only the matching fields from the
second-level of all HierarchicalKeywords structures:</p>

<blockquote><table class='box'><tr><td>
<pre class=code>exiftool -hierarchicalkeywords2-="Terrier" a.jpg</pre>
</td></tr></table></blockquote>

<p>Individual structure <b>fields may NOT be deleted by writing a structure</b>
with an empty field.  Instead, a command like this overwrites the entire
structure with a new structure containing an empty field:</p>

<blockquote><table class='box'><tr><td>
<pre><span class=code>exiftool -CreatorContactInfo="{CiAdrCity=}" a.jpg</span>  # WRONG!</pre>
</td></tr></table></blockquote>

<p>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.</p>

<a name='Fields'></a>
<h2>Field Names</h2>

<p>Structure field names use a format <b>very similar to tag names</b> in
ExifTool.  The following table lists some similarities and differences
between tag names and structure field names:</p>

<blockquote><table border=1 cellspacing=0 cellpadding=4 width='100%'>
<tr><th>Feature</th><th>Example</th><th>Tag Names</th><th>Field Names</th></tr>
<tr align=center><td align=left>Case Insensitivity</td><td>Title, title, TITLE</td>
<td class=grn>Yes</td><td class=grn>Yes</td></tr>
<tr align=center><td align=left>Alternate Language Suffix</td><td>Title-de</td>
<td class=grn>Yes</td><td class=grn>Yes</td></tr>
<tr align=center><td align=left>Numerical Value Suffix</td><td>Mode#</td>
<td class=grn>Yes</td><td class=grn>Yes</td></tr>
<tr align=center><td align=left>Group Name Prefix</td><td>XMP-dc:Title</td>
<td class=grn>Yes</td><td class=red>No<sup>&dagger;</sup></td></tr>
</table>
<sup class=red>&dagger;</sup> Except that group name prefixes are
allowed in structures which support arbitrary XMP fields (eg.
<a href='TagNames/MWG.html#Extensions'>Region Extensions</a>)
</blockquote>

<a name='Serialize'></a>
<h2>Serialization</h2>

Structures are <b>serialized when reading or writing from the command line</b>.
However, serialization is not done when reading via the API, and is optional when
writing via the API.  The serialization algorithm is as follows:

<ol>
<li>Escape the following characters in string values (structure field values and
list items) by adding a leading pipe symbol (<code>|</code>):
<ul>
<li class=c>pipe symbols (<code>|</code>) and commas (<code>,</code>) anywhere in the string</li>
<li class=c>closing curly brackets (<code>}</code>) anywhere in structure field values</li>
<li class=c>closing square brackets (<code>]</code>) anywhere in list items</li>
<li class=c>an opening curly (<code>{</code>) or square (<code>[</code>)
bracket, or whitespace character (SPACE, TAB, CR or LF) if it appears at the
beginning of the string</li>
</ul>
<span class=lt>(Note: Any other character may be escaped by adding
a leading pipe symbol without effect.)</span></li>
<li>Enclose structures in curly brackets.  Use an equal sign (<code>=</code>)
to separate field names from their corresponding values, and a comma between
structure fields.</li>
<li>Enclose lists in square brackets, with a comma between list items.</li>
<li>Optional whitespace padding may be added anywhere except inside a structure
field name, or inside or after a string value, and an optional comma may be
added after the last field in a structure.</li>
</ol>

<p>For example, with this command:</p>

<blockquote><table class='box'><tr><td>
<pre class=code>exiftool "-RegionInfo&lt;=INFILE" a.xmp</pre>
</td></tr></table></blockquote>

<p>the INFILE below writes structured information to XMP-mwg-rs:RegionInfo.</p>

<blockquote><table class='box'><tr><td>
<pre>{
  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 = Evaluated|, Used,
    }
  ],
}</pre>
</td></tr></table></blockquote>

<p>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 consisting of a zero-length string.)</p>

<a name='Examples'></a>
<h2>Examples</h2>

<p>Here is an example of an advanced console session showing some commands which
manipulate a complex list of structures (see the
<a href="TagNames/XMP.html#iptcExt">XMP-iptcExt tag documentation</a> for details
about the ArtworkOrObject structure tags used):</p>

<blockquote><table class='box'><tr><td>
<pre><span class=lt># 1. Create a XMP-iptcExt:ArtworkOrObject structure using flattened tags</span>
&gt; <span class=code>exiftool -artworktitle="a title" a.xmp</span>
    1 image files created

<span class=lt># -- Read back as flattened tags (-S is used just to shorten the output)</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S a.xmp</span>
ArtworkTitle: a title

<span class=lt># -- Read back as a structure</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
ArtworkOrObject: [{AOTitle=a title}]

<span class=lt># 2. Write another field to the structure as a flattened tag</span>
&gt; <span class=code>exiftool -artworkcreator=phil a.xmp</span>
    1 image files updated

<span class=lt># -- Note that the structure now has a new field</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
ArtworkOrObject: [{AOCreator=[phil],AOTitle=a title}]

<span class=lt># 3. Add another creator using the "+=" operator</span>
&gt; <span class=code>exiftool -artworkcreator+=joe a.xmp</span>
    1 image files updated

<span class=lt># -- It was added to the first AOCreator list</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
ArtworkOrObject: [{AOCreator=[phil,joe],AOTitle=a title}]

<span class=lt># 4. Add another artwork title</span>
&gt; <span class=code>exiftool -artworktitle+="another one" a.xmp</span>
    1 image files updated

<span class=lt># -- This created a new ArtworkOrObject structure in the list of structures
# (AOTitle itself is not a list, so a new structure must be created)</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
ArtworkOrObject: [{AOCreator=[phil,joe],AOTitle=a title},{AOTitle=another one}]

<span class=lt># 5. Simply write a different title (do not add with "+=")</span>
&gt; <span class=code>exiftool -artworktitle="different" a.xmp</span>
    1 image files updated

<span class=lt># -- This deleted all existing AOTitle fields and wrote back only one
# (if the second ArtworkOrObject structure had contained more fields, they would have been
# preserved, and the second structure would still exist, but without an AOTitle field)</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
ArtworkOrObject: [{AOCreator=[phil,joe],AOTitle=different}]

<span class=lt># 6. Add a completely new structure to the list
# (this is very difficult to do properly using flattened tags)</span>
&gt; <span class=code>exiftool -artworkorobject+="{aotitle=help,aocreator=[paul,ringo]}" a.xmp</span>
    1 image files updated

<span class=lt># -- The new structure was added with the specified fields</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
ArtworkOrObject: [{AOCreator=[phil,joe],AOTitle=different},{AOCreator=[paul,ringo],AOTitle=help}]

<span class=lt># -- See how the relationships are lost when reading as flattened tags</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S a.xmp</span>
ArtworkCreator: phil, joe, paul, ringo
ArtworkTitle: different, help

<span class=lt># 7. Delete all structures containing a specific field value</span>
&gt; <span class=code>exiftool -artworkorobject-="{AOCreator=phil}" a.xmp</span>
    1 image files updated

<span class=lt># -- The ArtworkOrObject list now contains only one structure</span>
&gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
ArtworkOrObject: [{AOCreator=[paul,ringo],AOTitle=help}]</pre></td></tr></table></blockquote>

<a name='User'></a>
<h2>User-Defined Structures</h2>

<p>User-defined XMP structure tags may be created via the ExifTool config file.
See the NewXMPxxxStruct tag definition in the <a href="config.html#xmp-xxx">XMP-xxx
examples of the sample config file</a> for more details.</p>

<hr>
<i>Last revised Sept. 7, 2016</i>
<p class='lf'><a href="index.html">&lt;-- Back to ExifTool home page</a></p>
</body>
</html>