Set XMP Media Management Metadata
Document.SetMediaManagement writes the xmpMM: namespace: the document and
instance identifiers, the version number, and the DerivedFrom reference that links
a new file to the one it came from. Most of it is generated for you, and the one
decision you have to make is whether this write produces a new document or a new
version of the same one.
NewDocumentID | Effect |
|---|---|
false (default) | Keeps the existing DocumentID. Use it when the file is being modified in place. |
true | Generates a fresh DocumentID and records the previous one under DerivedFrom. Use it when saving to a new file. |
Either way a new InstanceID is generated, because the bytes changed.
Doing it
err := xmpDoc.SetMediaManagement(&xmputil.MediaManagementOptions{
NewDocumentID: true,
})
if err != nil {
return err
}
metadataBytes, err := xmpDoc.MarshalIndent("", "\t")
if err != nil {
return err
}
metadataStream, err := core.MakeStream(metadataBytes, nil)
if err != nil {
return err
}
return pdfWriter.SetCatalogMetadata(metadataStream)Load the existing packet first with GetCatalogMetadata, core.GetStream and
xmputil.LoadDocument, falling back to xmputil.NewDocument. It matters more here
than elsewhere: SetMediaManagement reads the current DocumentID, InstanceID and
VersionID off the packet to build DerivedFrom and to work out the next version.
Start from an empty document and there is no history to derive from.
Passing nil options is valid and does the default thing: keep the document ID if
there is one, generate one if not, generate a new instance ID, and increment the
version.
VersionID increments automatically. If the existing value parses as an integer the
next one is that plus one; if it does not parse, the number of recorded versions plus
one is used; with no previous value it starts at 1. An explicit VersionID in the
options is only honored when the packet has no version yet.
Limitations
Several documented fields on MediaManagementOptions are not read by the current
implementation: OriginalDocumentID, DerivedFrom, ModifyComment, ModifyDate
and Modifier. Setting them has no effect, and no error is returned. Only
DocumentID, NewDocumentID, InstanceID and VersionID reach the packet.
That means xmpMM:OriginalDocumentID is not written by this call, and it is not
generated either, despite what the field comment suggests. To set it, go through the
go-xmp model:
mmModel, err := xmpmm.MakeModel(xmpDoc.GetGoXmpDocument())
if err != nil {
return err
}
mmModel.OriginalDocumentID = xmp.GUID("56119f84-a812-484a-bb4c-61c7e7cb3265")Version history is likewise not written. xmpMM:Versions reads back empty on a file
whose metadata UniPDF produced, so the comment and modifier that belong to a version
entry have nowhere to go.
DerivedFrom is only populated from what the loaded packet already held. A document
with no previous DocumentID or InstanceID gets no DerivedFrom at all, even with
NewDocumentID: true.
Run the example
The example copies the input to a writer, loads or creates the XMP packet, calls
SetMediaManagement with NewDocumentID: true, and writes the packet to the output
file. Inspect the result with the
get media management metadata example. Note that
the OriginalDocumentID, ModifyComment, ModifyDate and Modifier options it
passes are ignored, so the original document ID will not appear in the output.
git clone https://github.com/unidoc/unipdf-examples.git
cd unipdf-examples/metadata
go run pdf_set_xmp_media_management_metadata.go input.pdf output.pdfIf this is your first time using UniPDF, follow the getting started guide to create an API key and set up your development environment.