Sample code for 30+ languages & platforms
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

C
#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);

    }