writing mwg hierarchical keywords

Started by MATadata, October 23, 2014, 03:24:17 PM

Previous topic - Next topic

MATadata

Hello,

I'm trying to write a keyword hierarchy using the mwg-kw keyword hierarchy to a jpg File. For this purpose I'm using a Powershell script. The hierarchy looks like this (example):

Animal
   Ape
   Horse
      Quarter horse
   Goose
Place
   England

   
I would like to write the hierarchy step by step (so not a complete hierarchy as
exiftool -hierarchicalkeywords+="{keyword=Animal,children={keyword=Horse,children={keyword=Quarterhorse}}}" C:\Picture.jpg.
Instead I would like to append the elements (finally in a loop when it comes to more complex hierarchies)


My Powershell script looks like this:

$File="Example.jpg"
$a="animal"
$b="ape"
$bb="horse"
$c="quarter horse"
$d="goose"
$e="Place"
$f="England"
exiftool `"-hierarchicalkeywords+="{keyword=$a}"`" $File
exiftool `"-hierarchicalkeywords2+="$b"`" $File
exiftool `"-hierarchicalkeywords2+="$bb"`" $File
exiftool `"-hierarchicalkeywords3+="$c"`" $File
exiftool `"-hierarchicalkeywords2+="$d"`" $File  
exiftool `"-hierarchicalkeywords+="{keyword=$e}"`" $File
exiftool `"-hierarchicalkeywords2+="$f"`" $File


When the script has finished the keyword hierarchy looks like this.


<rdf:Description rdf:about=''
  xmlns:mwg-kw='http://www.metadataworkinggroup.com/schemas/keywords/'>
  <mwg-kw:Keywords rdf:parseType='Resource'>
   <mwg-kw:Hierarchy>
    <rdf:Bag>
     <rdf:li rdf:parseType='Resource'>
      <mwg-kw:Children>
       <rdf:Bag>
        <rdf:li rdf:parseType='Resource'>
         <mwg-kw:Children>
          <rdf:Bag>
           <rdf:li rdf:parseType='Resource'>
            <mwg-kw:Keyword>quarterhorse</mwg-kw:Keyword>
           </rdf:li>
          </rdf:Bag>
         </mwg-kw:Children>
         <mwg-kw:Keyword>ape</mwg-kw:Keyword>
        </rdf:li>
        <rdf:li rdf:parseType='Resource'>
         <mwg-kw:Keyword>horse</mwg-kw:Keyword>
        </rdf:li>
        <rdf:li rdf:parseType='Resource'>
         <mwg-kw:Keyword>goose</mwg-kw:Keyword>
        </rdf:li>
        <rdf:li rdf:parseType='Resource'>
         <mwg-kw:Keyword>England</mwg-kw:Keyword>
        </rdf:li>
       </rdf:Bag>
      </mwg-kw:Children>
      <mwg-kw:Keyword>animal</mwg-kw:Keyword>
     </rdf:li>
     <rdf:li rdf:parseType='Resource'>
      <mwg-kw:Keyword>Place</mwg-kw:Keyword>
     </rdf:li>
    </rdf:Bag>
   </mwg-kw:Hierarchy>
  </mwg-kw:Keywords>
</rdf:Description>


It seems that the hierarchy that I intendend is complety upside down.
How can I fix this?

Thanks

Phil Harvey

First, I would combine all of your commands into one.  Doing this as separate commands is very inefficient.

In general it isn't possible to organize complex lists of structures using flattened tag names.  This must be done using structured tags.  I would suggest writing the individual HierarchicalKeywords structures.

I'm not sure I helped much, but I'm a bit short on time so I can't think about this more.

- 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 ($).

MATadata

Thanks Phil for your  answer. It definitely helped.

The problem with writing the individual HierarchicalKeywords structures seems to be that I can write a complete hierarchy with something like
exiftool -hierarchicalkeywords+="{keyword=Animal,children={keyword=Horse,children={keyword=Quarterhorse}}}" C:\Picture.jpg
,but I'm not able to add keywords of a certain level as the script comes across them.

As I indicated in my first post, the end goal was something like reading out the hierarchical keywords e.g. in the hierarchical subject filed of the XMP:lr part, storing them in an multidimensional array and copying them to the mwg-kw section. Seems like I have to give up that plan.

-MAT

Phil Harvey

Hi Mat,

If you use a Perl script and the API, it is easier to add a keyword at whatever level you want.  But via the command-line interface, I'm afraid you are forced into parsing the serialized structure yourself.  I'm assuming that you have seen the structure documentation.

- Phil

Edit:  Or maybe the JSON output format would help you here.  If your script can read JSON, then this may be a more convenient way to read/write these structures.
...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 ($).

MATadata

Hi Phil,

I've indeed looked at the structure documentation (that's where my principle command-line commands came from). I have to admit I have a basic knowledge of Powershell scripting, but no knowledge of Perl at all.  So maybe the way via JSON is kind of a balanced solution. However, thanks for your hint. Maybe I can dig in the Perl langauge and will retry with Perl and the API, which if I understand correctly is the best and technically most elegant way of doing these things.

Thanks for your help.

-MAT

Phil Harvey

Hi Mat,

Just to get you pointed in the right direction, this script adds a new 3rd-level keyword to the first hierarchical keywords structure:

#!/usr/bin/perl -w
use strict;
use Image::ExifTool;

my $file = shift || die "Need a file name\n";

my $et = new Image::ExifTool;
$et->Options(Struct => 1);
my $info = $et->ImageInfo($file);
my $kw = $$info{KeywordInfo} || { };

push @{$$kw{Hierarchy}[0]{Children}[0]{Children}}, {Keyword=>'plowhorse'};

$et->SetNewValue(KeywordInfo => $kw);
$et->WriteInfo($file);


I admit that it is still very confusing to dig down to this level in the MWG keyword structure.  But at least possible.

- 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 ($).

MATadata

Hi Phil,

thanks for the code snippet. It will be a good starting point for "exploring the secrets of Hierarchical Keywords" in Perl :)

- MAT