struct.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  2. "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
  3. <html>
  4. <head>
  5. <title>Structured Information</title>
  6. <link rel=stylesheet type='text/css' href='style.css' title='Style'>
  7. <style type="text/css">
  8. <!--
  9. pre { padding: 0; margin: 0px 2px }
  10. spc { margin-top: 5em }
  11. li { margin-top: .5em }
  12. li.c { margin-top: 0 }
  13. -->
  14. </style>
  15. </head>
  16. <body>
  17. <div class='index'>
  18. <a href="#Reading">Reading</a>
  19. <br><a href="#Writing">Writing</a>
  20. <br><a href="#Copying">Copying</a>
  21. <br><a href="#Deleting">Deleting</a>
  22. <br><a href="#Fields">Field Names</a>
  23. <br><a href="#Serialize">Serialization</a>
  24. <br><a href="#Examples">Examples</a>
  25. <br><a href="#User">User-Defined</a>
  26. </div>
  27. <h1 class='up'>Structured Information</h1>
  28. <p>ExifTool has the ability to read and write XMP structures through the use of
  29. either <b>structured or flattened tags</b>. The ability to write via structured
  30. input was added in ExifTool version 8.44; older versions wrote using flattened
  31. tags only.</p>
  32. <p>To illustrate the concept of a flattened tag, the <code>XMP-exif:Flash</code>
  33. structure contains <code>Fired</code> and <code>Mode</code> fields (among
  34. others). The flattened tags corresponding to these structure fields are
  35. <code>XMP-exif:FlashFired</code> and <code>XMP-exif:FlashMode</code>. In the
  36. <a href="TagNames/XMP.html">XMP Tags documentation</a>, flattened tags are
  37. indicated by an underline (<code>_</code>) after the Writable type.</p>
  38. <p>This page describes various techniques used to read and write XMP structures
  39. using both structured and flattened tags.</p>
  40. <a name='Reading'></a>
  41. <h2>Reading</h2>
  42. <p>When reading, structures are <b>flattened by default</b>, and ExifTool
  43. returns one "flattened" tag for each field in the structure:</p>
  44. <blockquote><table class='box'><tr><td>
  45. <pre>&gt; <span class=code>exiftool -xmp:all a.xmp</span>
  46. XMP Toolkit : Image::ExifTool 8.44
  47. Flash Fired : True
  48. Flash Mode : On
  49. Flash Return : Return not detected</pre>
  50. </td></tr></table></blockquote>
  51. <p>But the <code>-struct</code> option may be used to give <b>structured
  52. output</b>. In this mode structures are returned instead of separate
  53. "flattened" tags:</p>
  54. <blockquote><table class='box'><tr><td>
  55. <pre>&gt; <span class=code>exiftool -struct -xmp:all a.xmp</span>
  56. XMP Toolkit : Image::ExifTool 8.44
  57. Flash : {Fired=True,Mode=On,Return=Return not detected}</pre>
  58. </td></tr></table></blockquote>
  59. <p class=lt>(Note: As illustrated in the example above, structures are
  60. <a href='#Serialize'>serialized</a> for console output by the ExifTool
  61. application. However, via the API with the <code>Struct</code> option,
  62. they are returned as Perl HASH references.)</p>
  63. <p>The <code>-struct</code> option may also be combined with the JSON
  64. (<code>-j</code>), PHP (<code>-php</code>) or XML (<code>-X</code>) output
  65. formats to provide a structured format which may be more compatible with other
  66. applications.</p>
  67. <a name='Writing'></a>
  68. <h2>Writing</h2>
  69. <p>When writing, <b>flattened tags and structures may be used interchangeably</b>.
  70. For example, the following commands all have the same effect.</p>
  71. <blockquote><table class='box'><tr><td>
  72. <pre class=code>exiftool -flashmode=on -flashreturn=not -flashfired=true a.xmp
  73. exiftool -xmp:flash="{mode=on,fired=true}" -flashreturn=not a.xmp
  74. exiftool -xmp:flash="{mode=on,fired=true,return=not}" a.xmp</pre>
  75. </td></tr></table></blockquote>
  76. <p class=lt>(Note: Structures must be <a href='#Serialize'>serialized</a> when
  77. writing via the command-line application, in the same format as when reading with
  78. the <code>-struct</code> option.)</p>
  79. <p>An advantage of writing in structured form is that it can be easier to
  80. achieve the desired hierarchy with complex structures or when there are multiple
  81. structures in a list. For example, this command adds a new hierarchical keyword
  82. to the XMP-mwg-kw:HierarchicalKeywords list:</p>
  83. <blockquote><table class='box'><tr><td>
  84. <pre class=code>exiftool -hierarchicalkeywords+="{keyword=cat,children={keyword=Siamese}}" a.jpg</pre>
  85. </td></tr></table></blockquote>
  86. <p>But the flattened tags may be more convenient for <b>adding or replacing a
  87. single field</b> in an existing structure because writing as a structure would
  88. require that the entire structure be replaced. For example, the following command
  89. adds a new second-level keyword to an existing HierarchicalKeywords structure:</p>
  90. <blockquote><table class='box'><tr><td>
  91. <pre class=code>exiftool -hierarchicalkeywords2+="Persian" a.jpg</pre>
  92. </td></tr></table></blockquote>
  93. <p><b>Tricky:</b> There is one drawback when using this technique to add new
  94. fields to existing structures in lists: New fields are added to the first
  95. structure which doesn't already contain the corresponding field. So before
  96. adding a new field to a arbitrary structure, dummy fields must first be added to
  97. all earlier structures in the list which are missing this field. However, the
  98. alternative of adding a new field by writing structured information also has its
  99. drawbacks. Here, although a specific structure in a list can easily be targeted
  100. through any unique combination of field values, the drawback is that the entire
  101. structure must be replaced (see <a href="#Deleting">Deleting / Replacing</a>
  102. below).</p>
  103. <p>The flattened tag names may also be used to <b>write structures at any level
  104. in a complex hierarchy</b>. The following example writes a third-level
  105. structure inside a HierarchicalKeywords structure:</p>
  106. <blockquote><table class='box'><tr><td>
  107. <pre class=code>exiftool -hierarchicalkeywords2Children='{Keyword=Tabby,Applied=true}' a.jpg</pre>
  108. </td></tr></table></blockquote>
  109. <p class=lt>(Note: Containing structures are created as necessary. In this
  110. case, the HierarchicalKeywords and top-level KeywordInfo structures would be
  111. created if they didn't already exist.)</p>
  112. <p>The <b>order of structure fields is not significant</b>, so they may be read
  113. in a different order then written, unlike arrays which maintain the same order.
  114. To give a predictable output, fields in structured information are <b>sorted in
  115. alphabetical order</b> of field name by ExifTool when reading and writing.</p>
  116. <p>If there are <b>errors converting some fields</b> of the input structure,
  117. other fields are still written and a warning is issued (but only one warning per
  118. structure is reported). This also applies when copying structured information
  119. except that the <code>-v3</code> option must be used to see the warnings when
  120. copying.</p>
  121. <p><b>Programmers:</b> Structured information is written and read as Perl HASH
  122. references via the ExifTool API, but it may also be written as a serialized
  123. string. The following two techniques are equivalent:</p>
  124. <blockquote><table class='box'><tr><td>
  125. <pre># as a HASH reference
  126. <span class=code>$exifTool-&gt;SetNewValue('XMP:Flash' =&gt; { mode=>'on', fired=>'true', return=>'not' });
  127. </span>
  128. # as a serialized string
  129. <span class=code>$exifTool-&gt;SetNewValue('XMP:Flash' =&gt; '{mode=on,fired=true,return=not}');</span></pre>
  130. </td></tr></table></blockquote>
  131. <a name='Copying'></a>
  132. <h2>Copying</h2>
  133. <p>By default, tags are <b>copied as structures</b>, but flattened tag names
  134. may still be copied by specifying them explicitly. <span class=lt>(Flattened
  135. tags are treated as "unsafe" for copying so they are not copied by default
  136. unless the Struct feature is disabled.)</span> Copying as structures allows the
  137. hierarchy of complex structures to be preserved.</p>
  138. <blockquote><table class='box'><tr><td>
  139. <pre># this copies all XMP information as structures
  140. # (flattened tags are not copied by default...)
  141. <span class=code>exiftool -tagsfromfile src.jpg -xmp:all dst.jpg
  142. </span>
  143. # ... but flattened tags may be copied individually. Here the
  144. # first level hierarchical keywords are copied to the Subject tag
  145. # (this may be done in the same command as one that copies structures)
  146. <span class=code>exiftool -tagsfromfile src.jpg "-subject&lt;hierarchicalkeywords1" dst.jpg</span></pre>
  147. </td></tr></table></blockquote>
  148. <p>Note that when copying a specific structure, only the top-level structures
  149. may be specified:</p>
  150. <blockquote><table class='box'><tr><td>
  151. <pre># this copies the complete keyword hierarchy
  152. <span class=code>exiftool -tagsfromfile src.jpg -keywordinfo dst.jpg
  153. </span>
  154. # WRONG because HierarchicalKeywords is NOT a top-level structure!
  155. <span class=code>exiftool -tagsfromfile src.jpg -hierarchicalkeywords dst.jpg</span></pre>
  156. </td></tr></table></blockquote>
  157. <p>The copy-as-structure feature may be disabled with <code>--struct</code> on
  158. the command line, or by setting the <a href="ExifTool.html#Struct">Struct option</a>
  159. to 0 via the API. When this is done, only flattened tags are copied, and
  160. structures may not be specified. Conversely, if the structure option is enabled
  161. (by setting the <a href="ExifTool.html#Struct">Struct option</a> to 1 via the API,
  162. or with <code>-struct</code> on the command line), only structures are copied,
  163. and flattened tags may not be specified.</p>
  164. <p class=lt>(Note: ExifTool 8.43 and earlier copied as flattened tags only, but
  165. copying as structures has been the default since the ability to write structured
  166. information was introduced in version 8.44. An enhancement in version 8.82
  167. allowed flattened tags to be copied explicitly without the need to disable the
  168. Struct option.)</p>
  169. <a name='Deleting'></a>
  170. <h2>Deleting / Replacing</h2>
  171. <p>A <b>complete structure is deleted</b> by specifying one or more matching
  172. fields. For example, the following command deletes all HierarchicalKeywords
  173. structures which have the Keyword "<code>Terrier</code>" at the second level:</p>
  174. <blockquote><table class='box'><tr><td>
  175. <pre class=code>exiftool -hierarchicalkeywords-="{Children={Keyword=Terrier}}" a.jpg</pre>
  176. </td></tr></table></blockquote>
  177. <p>Structure <b>fields may also be deleted individually</b> using the flattened
  178. tag names. The following command deletes only the matching fields from the
  179. second-level of all HierarchicalKeywords structures:</p>
  180. <blockquote><table class='box'><tr><td>
  181. <pre class=code>exiftool -hierarchicalkeywords2-="Terrier" a.jpg</pre>
  182. </td></tr></table></blockquote>
  183. <p>Individual structure <b>fields may NOT be deleted by writing a structure</b>
  184. with an empty field. Instead, a command like this overwrites the entire
  185. structure with a new structure containing an empty field:</p>
  186. <blockquote><table class='box'><tr><td>
  187. <pre><span class=code>exiftool -CreatorContactInfo="{CiAdrCity=}" a.jpg</span> # WRONG!</pre>
  188. </td></tr></table></blockquote>
  189. <p>When deleting and adding back items in lists in the same command, new items
  190. are inserted at the point in the list where the first item was removed, or at
  191. the end of the list if no items were deleted. This applies to lists of
  192. structures as well as simple lists of string values, and provides a mechanism to
  193. replace a specific structure or field.</p>
  194. <a name='Fields'></a>
  195. <h2>Field Names</h2>
  196. <p>Structure field names use a format <b>very similar to tag names</b> in
  197. ExifTool. The following table lists some similarities and differences
  198. between tag names and structure field names:</p>
  199. <blockquote><table border=1 cellspacing=0 cellpadding=4 width='100%'>
  200. <tr><th>Feature</th><th>Example</th><th>Tag Names</th><th>Field Names</th></tr>
  201. <tr align=center><td align=left>Case Insensitivity</td><td>Title, title, TITLE</td>
  202. <td class=grn>Yes</td><td class=grn>Yes</td></tr>
  203. <tr align=center><td align=left>Alternate Language Suffix</td><td>Title-de</td>
  204. <td class=grn>Yes</td><td class=grn>Yes</td></tr>
  205. <tr align=center><td align=left>Numerical Value Suffix</td><td>Mode#</td>
  206. <td class=grn>Yes</td><td class=grn>Yes</td></tr>
  207. <tr align=center><td align=left>Group Name Prefix</td><td>XMP-dc:Title</td>
  208. <td class=grn>Yes</td><td class=red>No<sup>&dagger;</sup></td></tr>
  209. </table>
  210. <sup class=red>&dagger;</sup> Except that group name prefixes are
  211. allowed in structures which support arbitrary XMP fields (eg.
  212. <a href='TagNames/MWG.html#Extensions'>Region Extensions</a>)
  213. </blockquote>
  214. <a name='Serialize'></a>
  215. <h2>Serialization</h2>
  216. Structures are <b>serialized when reading or writing from the command line</b>.
  217. However, serialization is not done when reading via the API, and is optional when
  218. writing via the API. The serialization algorithm is as follows:
  219. <ol>
  220. <li>Escape the following characters in string values (structure field values and
  221. list items) by adding a leading pipe symbol (<code>|</code>):
  222. <ul>
  223. <li class=c>pipe symbols (<code>|</code>) and commas (<code>,</code>) anywhere in the string</li>
  224. <li class=c>closing curly brackets (<code>}</code>) anywhere in structure field values</li>
  225. <li class=c>closing square brackets (<code>]</code>) anywhere in list items</li>
  226. <li class=c>an opening curly (<code>{</code>) or square (<code>[</code>)
  227. bracket, or whitespace character (SPACE, TAB, CR or LF) if it appears at the
  228. beginning of the string</li>
  229. </ul>
  230. <span class=lt>(Note: Any other character may be escaped by adding
  231. a leading pipe symbol without effect.)</span></li>
  232. <li>Enclose structures in curly brackets. Use an equal sign (<code>=</code>)
  233. to separate field names from their corresponding values, and a comma between
  234. structure fields.</li>
  235. <li>Enclose lists in square brackets, with a comma between list items.</li>
  236. <li>Optional whitespace padding may be added anywhere except inside a structure
  237. field name, or inside or after a string value, and an optional comma may be
  238. added after the last field in a structure.</li>
  239. </ol>
  240. <p>For example, with a command like this:</p>
  241. <blockquote><table class='box'><tr><td>
  242. <pre class=code>exiftool "-RegionInfo&lt;=INFILE" a.xmp</pre>
  243. </td></tr></table></blockquote>
  244. <p>the INFILE below may be used to write structured information to
  245. XMP:RegionInfo.</p>
  246. <blockquote><table class='box'><tr><td>
  247. <pre>{
  248. AppliedToDimensions =
  249. {
  250. W = 4288,
  251. H = 2848,
  252. Unit = pixel,
  253. },
  254. RegionList =
  255. [
  256. {
  257. Area =
  258. {
  259. W = 0.15, H = 0.17, X = 0.3, Y = 0.4,
  260. Unit = normalized,
  261. },
  262. Description = A Physics Icon {relatively speaking|},
  263. Name = Albert Einstein,
  264. Type = Face,
  265. Extensions = {
  266. XMP-xmpRights:UsageTerms = copyright Phil Harvey,
  267. XMP-xmpRights:UsageTerms-fr = droit d'auteur Phil Harvey,
  268. },
  269. SeeAlso = dc:subject,
  270. },
  271. {
  272. Area =
  273. {
  274. W = 0.06, H = 0.09, X = 0.5, Y = 0.6,
  275. Unit = normalized,
  276. },
  277. Description = this is a test|, what did you expect?,
  278. Type = Focus,
  279. FocusUsage = Evaluated|, Used,
  280. }
  281. ],
  282. }</pre>
  283. </td></tr></table></blockquote>
  284. <p>In this example, white space has been added in all allowed locations for
  285. demonstration purposes and to improve readability. Also, optional commas have
  286. been added after the last field of each structure. (Note that a comma may NOT
  287. be added after the last item in a list because this would be interpreted as an
  288. additional list item of a zero-length string.)</p>
  289. <a name='Examples'></a>
  290. <h2>Examples</h2>
  291. <p>Here is an example of an advanced console session showing some commands which
  292. manipulate a complex list of structures (see the
  293. <a href="TagNames/XMP.html#iptcExt">XMP-iptcExt tag documentation</a> for details
  294. about the ArtworkOrObject structure tags used):</p>
  295. <blockquote><table class='box'><tr><td>
  296. <pre><span class=lt># 1. Create a XMP-iptcExt:ArtworkOrObject structure using flattened tags</span>
  297. &gt; <span class=code>exiftool -artworktitle="a title" a.xmp</span>
  298. 1 image files created
  299. <span class=lt># -- Read back as flattened tags (-S is used just to shorten the output)</span>
  300. &gt; <span class=code>exiftool -xmp-iptcext:all -S a.xmp</span>
  301. ArtworkTitle: a title
  302. <span class=lt># -- Read back as a structure</span>
  303. &gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
  304. ArtworkOrObject: [{AOTitle=a title}]
  305. <span class=lt># 2. Write another field to the structure as a flattened tag</span>
  306. &gt; <span class=code>exiftool -artworkcreator=phil a.xmp</span>
  307. 1 image files updated
  308. <span class=lt># -- Note that the structure now has a new field</span>
  309. &gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
  310. ArtworkOrObject: [{AOCreator=[phil],AOTitle=a title}]
  311. <span class=lt># 3. Add another creator using the "+=" operator</span>
  312. &gt; <span class=code>exiftool -artworkcreator+=joe a.xmp</span>
  313. 1 image files updated
  314. <span class=lt># -- It was added to the first AOCreator list</span>
  315. &gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
  316. ArtworkOrObject: [{AOCreator=[phil,joe],AOTitle=a title}]
  317. <span class=lt># 4. Add another artwork title</span>
  318. &gt; <span class=code>exiftool -artworktitle+="another one" a.xmp</span>
  319. 1 image files updated
  320. <span class=lt># -- This created a new ArtworkOrObject structure in the list of structures
  321. # (AOTitle itself is not a list, so a new structure must be created)</span>
  322. &gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
  323. ArtworkOrObject: [{AOCreator=[phil,joe],AOTitle=a title},{AOTitle=another one}]
  324. <span class=lt># 5. Simply write a different title (do not add with "+=")</span>
  325. &gt; <span class=code>exiftool -artworktitle="different" a.xmp</span>
  326. 1 image files updated
  327. <span class=lt># -- This deleted all existing AOTitle fields and wrote back only one
  328. # (if the second ArtworkOrObject structure had contained more fields, they would have been
  329. # preserved, and the second structure would still exist, but without an AOTitle field)</span>
  330. &gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
  331. ArtworkOrObject: [{AOCreator=[phil,joe],AOTitle=different}]
  332. <span class=lt># 6. Add a completely new structure to the list
  333. # (this is very difficult to do properly using flattened tags)</span>
  334. &gt; <span class=code>exiftool -artworkorobject+="{aotitle=help,aocreator=[paul,ringo]}" a.xmp</span>
  335. 1 image files updated
  336. <span class=lt># -- The new structure was added with the specified fields</span>
  337. &gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
  338. ArtworkOrObject: [{AOCreator=[phil,joe],AOTitle=different},{AOCreator=[paul,ringo],AOTitle=help}]
  339. <span class=lt># -- See how the relationships are lost when reading as flattened tags</span>
  340. &gt; <span class=code>exiftool -xmp-iptcext:all -S a.xmp</span>
  341. ArtworkCreator: phil, joe, paul, ringo
  342. ArtworkTitle: different, help
  343. <span class=lt># 7. Delete all structures containing a specific field value</span>
  344. &gt; <span class=code>exiftool -artworkorobject-="{AOCreator=phil}" a.xmp</span>
  345. 1 image files updated
  346. <span class=lt># -- The ArtworkOrObject list now contains only one structure</span>
  347. &gt; <span class=code>exiftool -xmp-iptcext:all -S -struct a.xmp</span>
  348. ArtworkOrObject: [{AOCreator=[paul,ringo],AOTitle=help}]</pre></td></tr></table></blockquote>
  349. <a name='User'></a>
  350. <h2>User-Defined Structures</h2>
  351. <p>User-defined XMP structure tags may be created via the ExifTool config file.
  352. See the NewXMPxxxStruct tag definition in the <a href="config.html#xmp-xxx">XMP-xxx
  353. examples of the sample config file</a> for more details.</p>
  354. <hr>
  355. <i>Last revised Nov. 25, 2014</i>
  356. <p class='lf'><a href="index.html">&lt;-- Back to ExifTool home page</a></p>
  357. </body>
  358. </html>