C
C
PDF Update or Add XML Metadata
Demonstrates how to add or update the XML metadata stored in a PDF.Note: This example requires Chilkat v10.1.0 or later.
Chilkat C Downloads
#include <C_CkPdf.h>
#include <C_CkXml.h>
#include <C_CkStringBuilder.h>
#include <C_CkDateTime.h>
void ChilkatSample(void)
{
BOOL success;
HCkPdf pdf;
HCkXml xml;
HCkStringBuilder sbExisting;
BOOL hasMetadata;
HCkDateTime dt;
const char *ts;
HCkStringBuilder sbDocId;
HCkStringBuilder sbInstanceId;
HCkStringBuilder sb;
success = FALSE;
// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
pdf = CkPdf_Create();
// Load a PDF file.
// If the PDF file already has metadata, we'll update it.
// Otherwise this example adds the metadata.
success = CkPdf_LoadFile(pdf,"qa_data/pdf/blank_with_metadata.pdf");
if (success == FALSE) {
printf("%s\n",CkPdf_lastErrorText(pdf));
CkPdf_Dispose(pdf);
return;
}
xml = CkXml_Create();
sbExisting = CkStringBuilder_Create();
hasMetadata = CkPdf_GetMetadata(pdf,sbExisting);
if (hasMetadata == TRUE) {
CkXml_LoadSb(xml,sbExisting,TRUE);
}
else {
// Otherwise create the bare minimum XMP metadata.
CkXml_putTag(xml,"x:xmpmeta");
CkXml_AddAttribute(xml,"xmlns:x","adobe:ns:meta/");
CkXml_AddAttribute(xml,"x:xmptk","Adobe XMP Core 9.1-c001 79.675d0f7, 2023/06/11-19:21:16 ");
CkXml_UpdateAttrAt(xml,"rdf:RDF",TRUE,"xmlns:rdf","http://www.w3.org/1999/02/22-rdf-syntax-ns#");
CkXml_UpdateAttrAt(xml,"rdf:RDF|rdf:Description",TRUE,"rdf:about","");
CkXml_UpdateAttrAt(xml,"rdf:RDF|rdf:Description",TRUE,"xmlns:xmp","http://ns.adobe.com/xap/1.0/");
CkXml_UpdateAttrAt(xml,"rdf:RDF|rdf:Description",TRUE,"xmlns:dc","http://purl.org/dc/elements/1.1/");
CkXml_UpdateAttrAt(xml,"rdf:RDF|rdf:Description",TRUE,"xmlns:xmpMM","http://ns.adobe.com/xap/1.0/mm/");
CkXml_UpdateAttrAt(xml,"rdf:RDF|rdf:Description",TRUE,"xmlns:pdf","http://ns.adobe.com/pdf/1.3/");
CkXml_UpdateAttrAt(xml,"rdf:RDF|rdf:Description",TRUE,"xmlns:xmpRights","http://ns.adobe.com/xap/1.0/rights/");
dt = CkDateTime_Create();
CkDateTime_SetFromCurrentSystemTime(dt);
ts = CkDateTime_getAsTimestamp(dt,TRUE);
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|xmp:ModifyDate",ts);
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|xmp:CreateDate",ts);
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|xmp:MetadataDate",ts);
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|xmp:CreatorTool","My Custom Application");
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|dc:format","application/pdf");
sbDocId = CkStringBuilder_Create();
CkStringBuilder_Append(sbDocId,"uuid:");
CkStringBuilder_AppendUuid(sbDocId,TRUE);
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|xmpMM:DocumentID",CkStringBuilder_getAsString(sbDocId));
sbInstanceId = CkStringBuilder_Create();
CkStringBuilder_Append(sbInstanceId,"uuid:");
CkStringBuilder_AppendUuid(sbInstanceId,TRUE);
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|xmpMM:InstanceID",CkStringBuilder_getAsString(sbInstanceId));
}
// Add our custom metadata tags to either the existing XML metdata, or the newly created metadata.
CkXml_UpdateAttrAt(xml,"rdf:RDF|rdf:Description",TRUE,"xmlns:zf","urn:ferd:pdfa:CrossIndustryDocument:invoice:1p0#");
CkXml_UpdateAttrAt(xml,"rdf:RDF|rdf:Description",TRUE,"rdf:about"," ");
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|zf:ConformanceLevel","BASIC");
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|zf:DocumentFileName","ZZZZZZ-invoice.xml");
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|zf:DocumentType","INVOICE");
CkXml_UpdateChildContent(xml,"rdf:RDF|rdf:Description|zf:Version","1.0");
// Create a new PDF with the updated metadata.
sb = CkStringBuilder_Create();
CkXml_GetXmlSb(xml,sb);
success = CkPdf_UpdateMetadata(pdf,sb,"c:/temp/qa_output/out.pdf");
if (success == TRUE) {
printf("Success\n");
}
else {
printf("%s\n",CkPdf_lastErrorText(pdf));
}
// To see the metadata in Adobe Acrobat DC,
// 1) Open the PDF.
// 2) CTRL-D to show the Document Properties dialog.
// 3) In the dialog, click on the "Additional Metadata" button.
// 4) In the Additional Data dialog, click on "Advanced"
// 5) Expand the namespace tree for the metadata you added.
printf("OK\n");
CkPdf_Dispose(pdf);
CkXml_Dispose(xml);
CkStringBuilder_Dispose(sbExisting);
CkDateTime_Dispose(dt);
CkStringBuilder_Dispose(sbDocId);
CkStringBuilder_Dispose(sbInstanceId);
CkStringBuilder_Dispose(sb);
}