Passing custom XMP metadata as JSON

Started by nico00152, February 13, 2020, 03:31:54 PM

Previous topic - Next topic

nico00152

I read this example for adding some custom xmp metadata:

exiftool -config categories.config -xmp-pdfx:categories="test" -pdf:categories="test" FILE

Config file:

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::XMP::pdfx' => {
        Categories => { },
    },
    'Image::ExifTool::PDF::Info' => {
        Categories => { List => 'string' },
    },
);

1;  #end

I was wondering, is it possible to set up the config file to accept a JSON object and add each key/value pair as individual properties? Something like this:

exiftool -config categories.config -xmp-pdfx:categories="{"prop1": "value1", "prop2": "value2"}" -pdf:categories="{"prop1": "value1", "prop2": "value2"}" FILE


I am using ExifTool in a Node.js project so rather than use a cli command I'd like to do this by modifying the config file to essentially create a schema for my custom data.


nico00152

Ok I made some progress.

This is my current config file:


%Image::ExifTool::UserDefined::TestCustom = (
    GROUPS        => { 0 => 'XMP', 1 => 'XMP-TestCustom', 2 => 'Image' },
    NAMESPACE     => { 'pdfx' => 'http://ns.adobe.com/pdfx/1.3/' },
    WRITABLE      => 'string',
    custom => {
        Struct => {
            X => { Writable => 'string'},
            Y => { Writable => 'string'},
        },
    },
);

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::XMP::pdfx' => {
        TestCustom => {
           SubDirectory => {
                TagTable => 'Image::ExifTool::UserDefined::TestCustom',
            },
        },

    },
    'Image::ExifTool::PDF::Info' => {
        TestCustom => {
           SubDirectory => {
                TagTable => 'Image::ExifTool::UserDefined::TestCustom',
            },
        },
    },
);


Which outputs:


custom: {X: 'this is x', Y: 'this is y'}


And this is the XML:


<rdf:Description rdf:about=''
  xmlns:pdfx='http://ns.adobe.com/pdfx/1.3/'>
  <pdfx:custom rdf:parseType='Resource'>
   <pdfx:X>this is x</pdfx:X>
   <pdfx:Y>this is y</pdfx:Y>
  </pdfx:custom>
</rdf:Description>


So now my question becomes: how do I modify my config so that the final xml is flattened out? EX:



<rdf:Description rdf:about=''
  xmlns:pdfx='http://ns.adobe.com/pdfx/1.3/'>
  <pdfx:X>this is x</pdfx:X>
  <pdfx:Y>this is y</pdfx:Y>
</rdf:Description>





Phil Harvey

To write what you want, you would do this:

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::XMP::pdfx' => {
            X => { },
            Y => { },
    },
);


That is the entire config file.  Notice I removed the PDF::Info tags because these wouldn't have worked anyway.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

nico00152

Phil, thanks for your reply. What if you don't know the names or values of properties X & Y? I want to be able to pass an object with properties that aren't always known.

Phil Harvey

Typically that is done with a different type of structure, something like this:

<rdf:Description rdf:about=''
  xmlns:pdfx='http://ns.adobe.com/pdfx/1.3/'>
  <rdf:Bag>
  <rdf:li>
  <pdfx:custom rdf:parseType='Resource'>
   <pdfx:Name>X</pdfx:Name>
   <pdfx:Value>this is x</pdfx:Value>
  </pdfx:custom>
  </rdf:li>
  <rdf:li>
  <pdfx:custom rdf:parseType='Resource'>
   <pdfx:Name>Y</pdfx:Name>
   <pdfx:Value>this is y</pdfx:Value>
  </pdfx:custom>
  </rdf:li>
  </rdf:Bag>
</rdf:Description>


- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).