Updating properties

The functions described in this section are available only for writable datasets, that is, datasets for which the isWritable() function returns true. Invoking any of these functions on a non-writable dataset is a programming error and has unpredictable results.

Finishing

finishWriting( )

Flushes any unsaved metadata changes to the backing file, closes the backing file, and turns the dataset into a read-only dataset. From now on, the isWritable() function returns false and further updates are impossible.

For a CP2 dataset, an appropriate Certified PDF 2 signature is written to the backing file, in addition to updating the XMP and CP2 data structures. These changes are affected through incremental save. Otherwise, the function behaves as before.

A writable dataset keeps its backing file open for updating after the dataset is created. Since the backing file is the current job (or a file in the job folder), it is necessary to close it before attempting to move or process job in any way. In practice it is seldom necessary to explicitly call the finishWriting() function because Switch automatically invokes it on the embedded dataset for a job at the following times:

Setting leaf values

The set functions described below set the value of a leaf property. They succeed if:

setString( xmp-path : String, prefix-map : Map, value : String ) : Boolean

Sets the value of the leaf property at the specified XMP location path to the specified string. Returns true if successful, false otherwise.

setNumber( xmp-path : String, prefix-map : Map, value : Number, precision : Number ) : Boolean

Same as setString but produces a decimal representation of the number; "precision" indicates the number of digits after the decimal point; if precision is zero the representation has no decimal point (that is, this is suitable for an integer number).

setBoolean( xmp-path : String, prefix-map : Map, value : Boolean ) : Boolean

Same as setString but produces the string "True" or "False" depending the Boolean value.

setDate( xmp-path : String, prefix-map : Map, value : Date ) : Boolean

Same as setString but produces a date-time representation in the ISO 8601 format. The class of the Date object is specific to the scripting environment in use.

Note:
  • To set the value of a child property, first verify that its parent exists, and if not, create the parent with the set functions described in the following section. It may be necessary to apply this process recursively to create the parent's parent.
  • To set the value of an item in an alt-text array, use the setLocalizedText() function described later. The above set functions do no allow a language selector in the specified XMP location path.

Setting localized text

setLocalizedText( xmp-path : String, prefix-map : Map, value : String, genericLang : String, specificLang: String ) : Boolean

Modifies the value of a selected item in an alt-text array. Creates an appropriate array item if necessary, and handles special cases for the x-default item.

If the selected item is from a match with the specific language, the value of that item is modified. If the existing value of that item matches the existing value of the x-default item, the x-default item is also modified. If the array only has 1 existing item (which is not x-default), an x-default item is added with the given value.

If the selected item is from a match with the generic language and there are no other generic matches, the value of that item is modified. If the existing value of that item matches the existing value of the x-default item, the x-default item is also modified. If the array only has 1 existing item (which is not x-default), an x-default item is added with the given value.

If the selected item is from a partial match with the generic language and there are other partial matches, a new item is created for the specific language. The x-default item is not modified.

If the selected item is from the last 2 rules then a new item is created for the specific language. If the array only had an x-default item, the x-default item is also modified. If the array was empty, items are created for the specific language and x-default.

Returns true if successful, false if the specified property does not exist or is not an Alt-Text array.

Adding structs and arrays

The set functions described below create struct or array properties. They succeed if:

setStruct( xmp-path : String, prefix-map : Map ) : Boolean

Creates a struct property at the specified XMP location path. Returns true if successful, false otherwise.

setUnorderedArray( xmp-path : String, prefix-map : Map ) : Boolean

Creates an unordered array property ("Bag") at the specified XMP location path. Returns true if successful, false otherwise.

setOrderedArray( xmp-path : String, prefix-map : Map ) : Boolean

Creates an ordered array property ("Seq") at the specified XMP location path. Returns true if successful, false otherwise.

setAlternateArray( xmp-path : String, prefix-map : Map ) : Boolean

Creates an alternate array property ("Alt") at the specified XMP location path. Returns true if successful, false otherwise.

Note: To change the type of a property between leaf, array and struct, first remove the property and then create it again with the appropriate set function. If the other property is not removed first, an error can be produced.

At some (already existing) location paths, it's impossible to randomly use setters, some paths are fully specified by the latest XMP spec.

Removing properties

removeProperty( xmp-path : String, prefix-map : Map )

Removes the property at the specified XMP location path and the complete sub-tree rooted at the property. If the property does not exist the function does nothing.

Use case

The following example makes use of the functions described in the whole XMP chapter.

//get a writable XMP Dataset
var ds = job.getEmbeddedDataset(true);
/*
 * add some XMP metadata to the file   
 */  

//get the default prefixmap  
var map = ds.createDefaultMap();

//add own namespaces
map.put('mns', 'MyNamespace');
map.put('mns2', 'MyNamespace2');

//own struct
ds.setStruct('mns:general', map);

//new author  
ds.setString('mns:general/mns:author', map, 'John Doe');

//new keywords  
ds.setUnorderedArray('mns:general/mns:keywords', map);
ds.setString('mns:general/mns:keywords/*[1]', map, 'sample');
ds.setString('mns:general/mns:keywords/*[2]', map, 'xmp');
ds.setString('mns:general/mns:keywords/*[3]', map, 'metadata');

//alttextarray  ds.setAlternateArray('mns:general/mns:subject', map);
ds.setLocalizedText('mns:general/mns:subject', map, 'Sample', 'en', 'en-US');
ds.setLocalizedText('mns:general/mns:subject', map, 'Voorbeeld', 'nl', 'nl-BE');
ds.setLocalizedText('mns:general/mns:subject', map, 'Exemple', 'fr', 'fr-FR');
ds.setLocalizedText('mns:general/mns:subject', map, 'Beispiel', 'de', 'de-DE');

//ordered array
ds.setOrderedArray('mns2:ordernrs', map);
ds.setNumber('mns2:ordernrs/*[1]', map, 7456);
ds.setNumber('mns2:ordernrs/*[2]', map, 3236);
ds.setNumber('mns2:ordernrs/*[3]', map, 9946);
ds.setNumber('mns2:ordernrs/*[4]', map, 1147);

//remove a property
ds.removeProperty('mns2:ordernrs/*[2]');

//datelist
ds.setOrderedArray('mns2:changedates');
ds.setDate('mns2:changedates/*[1]', map, new Date(Date.parse("2012-02-23T12:30:09")));
ds.setDate('mns2:changedates/*[2]', map, new Date(Date.parse("2012-02-24T14:33:22")));
ds.setDate('mns2:changedates/*[3]', map, new Date(Date.parse("2012-02-27T13:45:33")));
ds.setDate('mns2:changedates/*[4]', map, new Date(Date.parse("2012-02-29T11:24:19")));

//boolean  
ds.setBoolean('mns2:readOnly', map, true); 

//finished with writing
ds.finishWriting();

//save file  
job.sendToSingle(job.getPath()); 

Results in the following code segment:

<rdf:Description rdf:about=""
            xmlns:mns="MyNamespace/">
         <mns:general rdf:parseType="Resource">
            <mns:author>John Doe</mns:author>
            <mns:keywords>
               <rdf:Bag>
                  <rdf:li>sample</rdf:li>
                  <rdf:li>xmp</rdf:li>
                  <rdf:li>metadata</rdf:li>
               </rdf:Bag>
            </mns:keywords>
            <mns:subject>
               <rdf:Alt>
                  <rdf:li xml:lang="x-default">Sample</rdf:li>
                  <rdf:li xml:lang="en-US">Sample</rdf:li>
                  <rdf:li xml:lang="nl-BE">Voorbeeld</rdf:li>
                  <rdf:li xml:lang="fr-FR">Exemple</rdf:li>
                  <rdf:li xml:lang="de-DE">Beispiel</rdf:li>
               </rdf:Alt>
            </mns:subject>
         </mns:general>
      </rdf:Description>
      <rdf:Description rdf:about=""
            xmlns:mns2="MyNamespace2/">
         <mns2:ordernrs>
            <rdf:Seq>
               <rdf:li>7456</rdf:li>
               <rdf:li>9946</rdf:li>
               <rdf:li>1147</rdf:li>
            </rdf:Seq>
         </mns2:ordernrs>
         <mns2:changedates>
            <rdf:Seq>
               <rdf:li>2012-02-23T11:30:09Z</rdf:li>
               <rdf:li>2012-02-24T13:33:22Z</rdf:li>
               <rdf:li>2012-02-27T12:45:33Z</rdf:li>
               <rdf:li>2012-02-29T10:24:19Z</rdf:li>
            </rdf:Seq>
         </mns2:changedates>
         <mns2:readOnly>True</mns2:readOnly>
      </rdf:Description>