-
1. Re: Need help implimenting PLUS ldf in c++ via XMP sdk
Carl Rambert Apr 14, 2011 12:22 PM (in response to mpsimmons)I think that the rdf:resource=... is not appropriate goal in this
circumstance. I suspect that the PLUS examples were generated with
generic RDF tools, and not XMP-specific tools.
The MetaGrove Plug-in uses the c++ XMP SDK. The corresponding XMP
snippet generated by the MetaGrove Plug-in for Photoshop with PLUS
dialog is:
<plus:Licensee>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<plus:LicenseeName>ABC Advertising Agency</plus:LicenseeName>
<plus:LicenseeID>http://plus-id.org/AAA-987</plus:LicenseeID>
</rdf:li>
</rdf:Seq>
</plus:Licensee>
The IPTC-PLUS Extension for Bridge which probably uses the
extendScript version of the XMP SDK generates an identical snippet.
Regards,
Carl Rambert, Pound Hill Software
-
2. Re: Need help implimenting PLUS ldf in c++ via XMP sdk
Michael Beasley - Picade Apr 15, 2011 12:24 PM (in response to Carl Rambert)I have to second Carl's response: I have also long tortured and abused both the c++ and java versions of the Adobe XMP SDK (since the 3.x versions, now using the 5.1.2 c++ version) attempting to generate the appropriate qualifiers for the
- Licensee
- EndUser
- Licensor
- ImageCreator,
- ImageSupplier
structures as documented at http://ns.useplus.org/LDF/ldf-XMPSpecification, and also noted that the actual generated XMP for these items generated from Photoshop/Bridge CS5 did not match that documentation, and finally emailled Jeff at Plus asking for clarification of the documentation. If I ever actually get that clarification, I will post it to this thread.
In the meantime, my own code for the ImageCreator and similar arrays is:
////////////////////////////////////////////////////////////////////////////////////////
// Create the ImageCreator array of structures
string myLastArrayItemPath;
string myLastFieldPath;
theXmpMetadata.AppendArrayItem( kXMP_NS_PlusLDF, "ImageCreator", kXMP_PropArrayIsOrdered, 0, kXMP_PropValueIsStruct );// Compose a path to the last item of the ImageCreator array, this gives the path to the structure
SXMPUtils::ComposeArrayItemPath( kXMP_NS_PlusLDF, "ImageCreator", kXMP_ArrayLastItem, &myLastArrayItemPath );// Add the ImageCreatorID field
SXMPUtils::ComposeStructFieldPath( kXMP_NS_PlusLDF, myLastArrayItemPath.c_str(), kXMP_NS_PlusLDF, "ImageCreatorID", &myLastFieldPath);
theXmpMetadata.SetProperty( kXMP_NS_PlusLDF, myLastFieldPath.c_str(), "Example_ImageCreatorID", 0);// add the ImageCreatorName field
SXMPUtils::ComposeStructFieldPath( kXMP_NS_PlusLDF, myLastArrayItemPath.c_str(), kXMP_NS_PlusLDF, "ImageCreatorName", &myLastFieldPath);
theXmpMetadata.SetProperty( kXMP_NS_PlusLDF, myLastFieldPath.c_str(), "Example_ImageCreatorName", 0);HTH.
Cordially,
Michael Beasley, metadata and code geek/consultant for Picade LLC - a photographer owned stock and assignment agency
-
3. Re: Need help implimenting PLUS ldf in c++ via XMP sdk
JeffSedliki Apr 18, 2011 10:18 PM (in response to Michael Beasley - Picade)"the actual generated XMP for these items generated from Photoshop/Bridge CS5 did not match that documentation, and finally emailled Jeff at Plus asking for clarification of the documentation."
You rang?
;->
I'm looking into this issue and will report back...
Jeff
www.usePLUS.org -
-
5. Re: Need help implimenting PLUS ldf in c++ via XMP sdk
Roberto_Garcia Apr 21, 2011 2:07 PM (in response to mpsimmons)Hi,
I'm not a XMP expert but I've been working for some years with Semantic Web technologies. My understanding is that XMP is a subset of RDF (one of the main pieces of the Semantic Web) so I will try to make my contribution to this problem from there.
Consequently, looking at your problematic piece of XMP:
<plus:Licensee>
<rdf:Seq>
<rdf:li>
<rdf:type rdf:resource="plus:LicenseeDetail"/>
<plus:LicenseeID>http://plus-id.org/AAA-987</plus:LicenseeID>
<plus:LicenseeName>ABC Advertising Agency</plus:LicenseeName>
</rdf:li>
</rdf:Seq>
</plus:Licensee>
I can say that it isn't valid RDF so it shouldn't be proper XMP. This can be confirmed looking at the example for the property plus:Licensee available from the specification (http://ns.useplus.org/LDF/ldf-XMPSpecification#Licensee):
<plus:Licensee>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<rdf:type rdf:resource="plus:LicenseeDetail"/>
<plus:LicenseeID>http://plus-id.org/AAA-987</plus:LicenseeID>
<plus:LicenseeName>ABC Advertising Agency</plus:LicenseeName>
</rdf:li>
</rdf:Seq>
</plus:Licensee>
I have marked in bold where the problem is. Your piece of XML is missing the rdf:parseType="Resource" construct. I will explain why this is necessary from what I know from RDF. RDF is based on a graph model. There are resources, which correspond to graph nodes and represent the things the RDF metadata is talking about, and properties, which correspond to graph edges and represent the attributes and relations used to say things about the resources.
In RDF the convention is to use lowercase names for properties. This doesn't seem to be the convention in XMP so we must take a closer look at the XMP piece in order to identify what parts correspond to resources and to properties. From the LDF specification we know that plus:Licensee correspond to a property so it should link to a resource, in this case rdf:Seq (more specifically it is an anonymous resource (no id provided) of type rdf:Seq). Your example should have some additional markup before plus:Licensee, surely the resource that represents the licensee about which we are specifying the licensee using the plus:Licensee property.
Now, if we continue from the resource of type rdf:Seq, there is the rdf:li property (lower case as it is directly reused from the RDF specification). The problem now is that if we look directly inside rdf:li property we find rdf:type, plus:LicenseeID and plus:LicenseeName. It is clear that rdf:type (lowercase) is a property and from the LDF specification we can see that the other two also correspond to properties. Therefore, there is the problem. We have a property (rdf:li) pointing to three properties (rdf:type,...) so we are breaking the graph data model: nodes (resources) are connected through edges (properties) that link two nodes.
This is not the case for the example in the LDF specification. The rdf:parseType="Resource" constructs is a shortcut for:
<rdf:li>
<rdf:Resource>
<rdf:type rdf:resource="plus:LicenseeDetail"/>
<plus:LicenseeID>http://plus-id.org/AAA-987</plus:LicenseeID>
<plus:LicenseeName>ABC Advertising Agency</plus:LicenseeName>
</rdf:Resource>
</rdf:li>
It basically says that the following properties should be parsed as being connected to an anonymous resource. In order to make it clearer, it is helpful to look at the graph behing that markup. For instance, you can use the RDF2SVG service and render the graph behind the example from the specification (which I have make available from a custom URL):
I hope all this makes it clearer.
Best,
Roberto García
-
6. Re: Need help implimenting PLUS ldf in c++ via XMP sdk
Michael Beasley - Picade Apr 22, 2011 3:01 PM (in response to Roberto_Garcia)Professor Garcia,
thank you for the help, I think that you have clarified things greatly!
I should also say that I have noted another issue with the extant Plus ldf documentation which goes to partly explaining my own confusion, in that the online specification at http://ns.useplus.org/LDF/ldf-XMPSpecification specific item revision information apparently has also not been properly maintained over time, viz. with respect to Licensee, http://ns.useplus.org/LDF/ldf-XMPSpecification#Licensee
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Locally captured "print to pdf" version of online documentation at http://ns.useplus.org/LDF/ldf-XMPSpecificationfrom 2008.11.14 @ 12:49:11 CST
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++2. Licensee
XMP Property plus:Licensee
XMP Value Type Seq LicenseeDetail
XMP Category External
Description Party or parties to whom the license is granted by the Licensor/s under the license transaction.
Comments In the event that the Licensor grants rights to two or more parties under the license, multiple Licensees may be listed.
Cardinality 0..3
Example
<plus:Licensee>
<rdf:Seq>
<rdf:li>
<rdf:type rdf:resource="plus:LicenseeDetail"/>
<plus:LicenseeID>http://plus-id.org/AAA-987</plus:LicenseeID>
<plus:LicenseeName>ABC Advertising Agency</plus:LicenseeName>
</rdf:li>
</rdf:Seq>
</plus:Licensee>
Revisions1. Added this field as a parent to the other Licensee fields. (V1.1.0, R3)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Online version at http://ns.useplus.org/LDF/ldf-XMPSpecification#Licensee, 2011.04.22 @15:52:10 CDT
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2. Licensee
XMP Property plus:Licensee
XMP Value Type Seq LicenseeDetail
XMP Category External
Namespace URI http://ns.useplus.org/ldf/xmp/1.0/Licensee
Description Party or parties to whom the license is granted by the Licensor/s under the license transaction.
Comments In the event that the Licensor grants rights to two or more parties under the license, multiple Licensees may be listed.
Cardinality 0..3
Example
<plus:Licensee>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<rdf:type rdf:resource="plus:LicenseeDetail"/>
<plus:LicenseeID>http://plus-id.org/AAA-987</plus:LicenseeID>
<plus:LicenseeName>ABC Advertising Agency</plus:LicenseeName>
</rdf:li>
</rdf:Seq>
</plus:Licensee>
Revisions1. Added this field as a parent to the other Licensee fields. (V1.1.0, R3)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Note that the revision field between my old captured version and the current online version MATCH, but the specific example XMP DOES NOT, and I have been checking for differences in the specific item revision field rather than the actual code example (MY BAD!!!) to attempt to update my own code to properly match the published specification, and that similar differences exist for the EndUser, Licensor, CopyrightOwner, and the ImageCreator structures, but that the ImageSupplier structure documentation appears consistent between the two versions I have.
I suspect that there may be similar revision confusion on the part of the OP, as I have seen pdf's on the net similar to the one I created and maintained locally of the Plus ldf specifications.
Now to get Plus to correct their documentation/specifications AND to finally generate the proper matching XMP from the XMP Toolkit! Thanks again.
Cordially, Michael Beasley
-
7. Re: Need help implimenting PLUS ldf in c++ via XMP sdk
JeffSedliki Apr 22, 2011 11:05 PM (in response to Michael Beasley - Picade)Hello Michael, thanks again for your questions and suggestions, Professor Garcia is a PLUS volunteer who provided invaluable assistance and advice in the original drafting of our License Data Format specification. His post here results directly from my request for his comments in response to this issue raised in this thread, to independently confirm that our understanding and approach is correct.
I've confirmed that the <rdf:type> elements which you are unable to generate are not necessary in XMP and we have removed them from the examples listed in our spec. Please note that although some of the in-line examples in our LDF XMP Specification were missing "rdf:parseType" attributes, all of these appeared correctly in our downloadable example file. These unintentional omissions have also been corrected. We strongly suggest the use of our downloadable example files.
The suggestion in your most recent post regarding our versioning was incorrect but understandable. The difference between the earlier spec and the spec in place at the time that you most recently copied it is of course the result of in-progress edits in response to this thread, shared among other expert volunteers advising PLUS. Had you copied it moments later, you would likely have found the version number updated to 1.2.1. That said, where we correct a minor error in presentation of the spec rather than a material revision to the spec itself, we may or may not elect to note that revision.
Please advise of any other issues related to the spec or to you adoption of the standards. As demonstrated here, we act quickly to resolve any such issues.
Cheers
Jeff
-
8. Re: Need help implimenting PLUS ldf in c++ via XMP sdk
mpsimmons Apr 23, 2011 8:40 AM (in response to JeffSedliki)Dear Jeff Sedlik,
thanks ever so for your and Professor Garcia's fast response and action on this thread.Because of an extremely short contract delivery time on the project I was working on (delivered just an hour ago in fact!) I contacted Michael Beasley offline at Picade and after many hours spent simultaneously trying to get the toolkit to emit the structure "type" entries with the path construction and item or qualification setting functions, Michael B hacked up string templating functions for the structures of interest using Professor Garcia's RDF suggestions, then parsed them into an SXMPMeta object using ParseFromBuffer() and appended that to the rest of the XMP generated via standard code calls in another SXMPMeta object using SXMPUtils::ApplyTemplate( ..., ..., kXMPTemplate_AddNewProperties | kXMPTemplate_ReplaceExistingProperties | kXMPTemplate_IncludeInternalProperties ) which then allowed our code to successfully pass all the contract unit tests for delivery.
Thank you from both Michael B and myself for you clarifications and published simplifications to the Plus Ldf spec, as we will now be able to remove the string parsing kludges and generate our needed Xmp the way it should be with normal code calls to the toolkit.
From my point of view your action ultimately solves the delemma I posted about.
Have a g'day mate!
Michael Simmons
-
9. Re: Need help implimenting PLUS ldf in c++ via XMP sdk
Alan Lillich Apr 27, 2011 10:18 AM (in response to mpsimmons)Michael,
Back to your original question about using the C++ API, the SDK includes XMPProgrammersGuide.pdf in the docs folder. This has detailed examples of using the C++ API for many cases, including some complex data models similar to the array of structures used by PLUS.
hope this helps,
Alan Lillich
Adobe Systems

