I will be grateful for any suggestions or corrections!
What works: using batchPlay, I can successfully read, update, and then write XMPMetadata for the current document, and subsequently read it back and my updates are present.
After reviewing posts by Simon Henke and Rob, I would anticipate that I could make a similar scenario work for layer metadata.
The scenario that does not work (code and results below):
- I can read the metadata (using batchPlay) for the current layer and create a XMPMeta object. The serialized result appears to be valid, with an empty <
rdf:Description/> element positioned in the DOM at the same location as it appears in the corresponding serialized document XMPMeta. - I can append an array item. The serialized XMPMeta object now includes the appended array item.
- I can write the metadata (using batchPlay). The batchPlay return value is an array of one element, which is an empty object
[{}]. There is no indication of anything other than success. - If I then re-read the metadata and create a new XMPMeta object(same code as before), the serialized result is the same as before, that is, lacking the appended array item.
The code I am using:
Code to read the layer metadata and inspect it:
const { action, app, core } = require("photoshop");
const { XMPMeta, XMPConst } = require("uxp").xmp;
function getLayerXMP() {
return action.batchPlay(
[
{
_obj: "get",
_target: {
_ref: [
{ _property: "XMPMetadataAsUTF8" },
{ _ref: "layer", _enum: "ordinal", _value: "targetEnum" },
],
},
},
],
{ synchronousExecution: true }
);
};
let xmpData = getLayerXMP();
let meta = new XMPMeta(xmpData);
let serialized = meta.serialize();
The resulting serialized value (omitting numerous blank lines after the last closing tag)
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 10.0-c000 79.4332aae, 2026/08/17-13:39:43 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""/>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>
Code to append an array item and inspect the updated metadata:
meta.appendArrayItem(XMPConst.NS_DC, "description", "Set description Here", 0, XMPConst.ARRAY_IS_ALTERNATIVE);
let serialized = meta.serialize();
The resulting serialized value (again, omitting numerous blank lines)
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 10.0-c000 79.4332aae, 2026/08/17-13:39:43 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:description>
<rdf:Alt>
<rdf:li>Set description Here</rdf:li>
</rdf:Alt>
</dc:description>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?>
The code to write the metadata:
async function setLayerXMP(xmpString) {
try {
return await core.executeAsModal(
async () => {
return await action.batchPlay(
[
{
_obj: "set",
_target: [
{ _property: "XMPMetadataAsUTF8" },
{ _ref: "layer", _enum: "ordinal", _value: "targetEnum" },
],
to: {
_obj: "XMPMetadataAsUTF8",
XMPMetadataAsUTF8: xmpString,
},
},
],
{ synchronousExecution: false });
}, { commandName: "Setting XMP..." });
} catch (error) {
console.error(error);
}
};
let result = await setLayerXMP(meta.serialize());
The (stringified) return value:
[{}]
If anyone can make any suggestions, or tell me where I’m hgoing wrong, please do!
Thanks