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
|
<!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="#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 wrote using flattened
tags only.</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>.</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>> <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>> <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>) 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
requires that 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 then 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 they may also be written as serialized
strings. The following two techniques are equivalent:</p>
<blockquote><table class='box'><tr><td>
<pre># as a serialized string
<span class=code>$exifTool->SetNewValue('XMP:Flash' => '{mode=on,fired=true,return=not}');
</span>
# as a HASH reference
<span class=code>$exifTool->SetNewValue('XMP:Flash' => { 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>. This allows the hierarchy
of complex structures to be preserved when copying. In this mode, only the
top-level structure tags 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 Struct option to 0 via the API. Here is an
example command that copies the hierarchical keywords using this technique:</p>
<blockquote><table class='box'><tr><td>
<pre class=code>exiftool -tagsfromfile src.jpg --struct "-hierarchicalkeywords*" dst.jpg</pre>
</td></tr></table></blockquote>
<p class=lt>(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.)</p>
<a name='Deleting'></a>
<h2>Deleting / Replacing</h2>
<p>A <b>complete structure is deleted</b> by specifying one or more matching
fields. 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>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>†</sup></td></tr>
</table>
<sup class=red>†</sup> Except that group name prefixes are
allowed in structures which support arbitrary XMP fields (ie.
<a href='TagNames/XMP.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 a command like this:</p>
<blockquote><table class='box'><tr><td>
<pre class=code>exiftool "-RegionInfo<=INFILE" a.xmp</pre>
</td></tr></table></blockquote>
<p>the INFILE below may be used to write structured information to
XMP: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 = EvaluatedUsed,
}
],
}</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 which is a zero-length string.)</p>
<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 Jan. 21, 2011</i>
<p class='lf'><a href="index.html"><-- Back to ExifTool home page</a></p>
</body>
</html>
|